package provider

import (
	"context"
	"fmt"

	"git.adyxax.org/adyxax/terraform-provider-forgejo/internal/client"
	"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
	"github.com/hashicorp/terraform-plugin-framework/datasource"
	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
	"github.com/hashicorp/terraform-plugin-framework/types"
)

type RepositoriesDataSource struct {
	client *client.Client
}

var _ datasource.DataSource = &RepositoriesDataSource{} // Ensure provider defined types fully satisfy framework interfaces
func NewRepositoriesDataSource() datasource.DataSource {
	return &RepositoriesDataSource{}
}

type RepositoriesDataSourceModel struct {
	Elements []RepositoryDataSourceModel `tfsdk:"elements"`
}
type RepositoryDataSourceModel struct {
	AllowFastForwardOnlyMerge     types.Bool                                `tfsdk:"allow_fast_forward_only_merge"`
	AllowMergeCommits             types.Bool                                `tfsdk:"allow_merge_commits"`
	AllowRebase                   types.Bool                                `tfsdk:"allow_rebase"`
	AllowRebaseExplicit           types.Bool                                `tfsdk:"allow_rebase_explicit"`
	AllowRebaseUpdate             types.Bool                                `tfsdk:"allow_rebase_update"`
	AllowSquashMerge              types.Bool                                `tfsdk:"allow_squash_merge"`
	ArchivedAt                    timetypes.RFC3339                         `tfsdk:"archived_at"`
	Archived                      types.Bool                                `tfsdk:"archived"`
	AvatarUrl                     types.String                              `tfsdk:"avatar_url"`
	CloneUrl                      types.String                              `tfsdk:"clone_url"`
	CreatedAt                     timetypes.RFC3339                         `tfsdk:"created_at"`
	DefaultAllowMaintainerEdit    types.Bool                                `tfsdk:"default_allow_maintainer_edit"`
	DefaultBranch                 types.String                              `tfsdk:"default_branch"`
	DefaultDeleteBranchAfterMerge types.Bool                                `tfsdk:"default_delete_branch_after_merge"`
	DefaultMergeStyle             types.String                              `tfsdk:"default_merge_style"`
	DefaultUpdateStyle            types.String                              `tfsdk:"default_update_style"`
	Description                   types.String                              `tfsdk:"description"`
	Empty                         types.Bool                                `tfsdk:"empty"`
	ExternalTracker               *RepositoryExternalTrackerDataSourceModel `tfsdk:"external_tracker"`
	ExternalWiki                  *RepositoryExternalWikiDataSourceModel    `tfsdk:"external_wiki"`
	Fork                          types.Bool                                `tfsdk:"fork"`
	ForksCount                    types.Int64                               `tfsdk:"forks_count"`
	FullName                      types.String                              `tfsdk:"full_name"`
	GloballyEditableWiki          types.Bool                                `tfsdk:"globally_editable_wiki"`
	HasActions                    types.Bool                                `tfsdk:"has_actions"`
	HasIssues                     types.Bool                                `tfsdk:"has_issues"`
	HasPackages                   types.Bool                                `tfsdk:"has_packages"`
	HasProjects                   types.Bool                                `tfsdk:"has_projects"`
	HasPullRequests               types.Bool                                `tfsdk:"has_pull_requests"`
	HasReleases                   types.Bool                                `tfsdk:"has_releases"`
	HasWiki                       types.Bool                                `tfsdk:"has_wiki"`
	HtmlUrl                       types.String                              `tfsdk:"html_url"`
	Id                            types.Int64                               `tfsdk:"id"`
	IgnoreWhitespaceConflicts     types.Bool                                `tfsdk:"ignore_whitespace_conflicts"`
	Internal                      types.Bool                                `tfsdk:"internal"`
	InternalTracker               *RepositoryInternalTrackerDataSourceModel `tfsdk:"internal_tracker"`
	Language                      types.String                              `tfsdk:"language"`
	LanguagesUrl                  types.String                              `tfsdk:"languages_url"`
	Link                          types.String                              `tfsdk:"link"`
	Mirror                        types.Bool                                `tfsdk:"mirror"`
	MirrorInterval                types.String                              `tfsdk:"mirror_interval"`
	MirrorUpdated                 timetypes.RFC3339                         `tfsdk:"mirror_updated"`
	Name                          types.String                              `tfsdk:"name"`
	ObjectFormatName              types.String                              `tfsdk:"object_format_name"`
	OpenIssuesCount               types.Int64                               `tfsdk:"open_issues_count"`
	OpenPrCounter                 types.Int64                               `tfsdk:"open_pr_counter"`
	OriginalUrl                   types.String                              `tfsdk:"original_url"`
	Owner                         *UserDataSourceModel                      `tfsdk:"owner"`
	//terraform does not support recursive schema definitions
	//Parent                        *RepositoryDataSourceModel                `tfsdk:"parent"`
	Permissions    *PermissionDataSourceModel         `tfsdk:"permissions"`
	Private        types.Bool                         `tfsdk:"private"`
	ReleaseCounter types.Int64                        `tfsdk:"release_counter"`
	RepoTransfer   *RepositoryTransferDataSourceModel `tfsdk:"repo_transfer"`
	Size           types.Int64                        `tfsdk:"size"`
	SshUrl         types.String                       `tfsdk:"ssh_url"`
	StarsCount     types.Int64                        `tfsdk:"stars_count"`
	Template       types.Bool                         `tfsdk:"template"`
	Topics         []types.String                     `tfsdk:"topics"`
	UpdatedAt      timetypes.RFC3339                  `tfsdk:"updated_at"`
	Url            types.String                       `tfsdk:"url"`
	WatchersCount  types.Int64                        `tfsdk:"watchers_count"`
	Website        types.String                       `tfsdk:"website"`
	WikiBranch     types.String                       `tfsdk:"wiki_branch"`
}

type RepositoryExternalTrackerDataSourceModel struct {
	Description   types.String `tfsdk:"description"`
	Format        types.String `tfsdk:"external_tracker_format"`
	RegexpPattern types.String `tfsdk:"external_tracker_regexp_pattern"`
	Style         types.String `tfsdk:"external_tracker_style"`
	Url           types.String `tfsdk:"external_tracker_url"`
}

type RepositoryExternalWikiDataSourceModel struct {
	Description types.String `tfsdk:"description"`
	Url         types.String `tfsdk:"external_wiki_url"`
}

type RepositoryInternalTrackerDataSourceModel struct {
	AllowOnlyContributorsToTrackTime types.Bool `tfsdk:"allow_only_contributors_to_track_time"`
	EnableIssueDependencies          types.Bool `tfsdk:"enable_issue_dependencies"`
	EnableTimeTracker                types.Bool `tfsdk:"enable_time_tracker"`
}

type RepositoryTransferDataSourceModel struct {
	Description types.String          `tfsdk:"description"`
	Doer        *UserDataSourceModel  `tfsdk:"doer"`
	Recipient   *UserDataSourceModel  `tfsdk:"recipient"`
	Teams       []TeamDataSourceModel `tfsdk:"teams"`
}

func (d *RepositoriesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
	resp.TypeName = req.ProviderTypeName + "_repositories"
}

func (d *RepositoriesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"elements": schema.ListNestedAttribute{
				Computed:            true,
				MarkdownDescription: "The list of repositories.",
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"allow_fast_forward_only_merge": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether fast forward only merges are allowed or not.",
						},
						"allow_merge_commits": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether merge commits are allowed or not.",
						},
						"allow_rebase": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether updating a pull request branch by rebase is allowed or not.",
						},
						"allow_rebase_explicit": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether rebase then merge commits are allowed or not.",
						},
						"allow_rebase_update": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether rebase then fast forward merges are allowed or not.",
						},
						"allow_squash_merge": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether squash merge commits are allowed on this repository or not.",
						},
						"archived_at": schema.StringAttribute{
							Computed:            true,
							CustomType:          timetypes.RFC3339Type{},
							MarkdownDescription: "The datetime at which the repository was archived.",
						},
						"archived": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is archived or not.",
						},
						"avatar_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The URL of the avatar for the repository.",
						},
						"clone_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The URL to clone the repository.",
						},
						"created_at": schema.StringAttribute{
							Computed:            true,
							CustomType:          timetypes.RFC3339Type{},
							MarkdownDescription: "The datetime at which the repository was created.",
						},
						"default_allow_maintainer_edit": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether maintainers have edit permissions by default or not.",
						},
						"default_branch": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The name of the default branch.",
						},
						"default_delete_branch_after_merge": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether pull request branches are deleted by default after a merge or not.",
						},
						"default_merge_style": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "Name of the default merge style.",
						},
						"default_update_style": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "Name of the default update style.",
						},
						"description": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "A description string.",
						},
						"empty": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is empty or not.",
						},
						"external_tracker": schema.SingleNestedAttribute{
							Attributes: map[string]schema.Attribute{
								"description": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "A description string.",
								},
								"external_tracker_format": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "External issue tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.",
								},
								"external_tracker_regexp_pattern": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "Regular Expression Pattern. The first captured group will be used in place of {index}.",
								},
								"external_tracker_style": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "External issue tracker Number Format.",
								},
								"external_tracker_url": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "A URL.",
								},
							},
							Computed: true,
						},
						"external_wiki": schema.SingleNestedAttribute{
							Attributes: map[string]schema.Attribute{
								"description": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "A description string.",
								},
								"external_wiki_url": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "A URL.",
								},
							},
							Computed: true,
						},
						"fork": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is a fork or not.",
						},
						"forks_count": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of times the repository has been forked.",
						},
						"full_name": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The full name of the repository.",
						},
						"globally_editable_wiki": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether anyone can edit the wiki or not.",
						},
						"has_actions": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the actions unit is enabled or not.",
						},
						"has_issues": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the issues unit is enabled or not.",
						},
						"has_packages": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the packages unit is enabled or not.",
						},
						"has_projects": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the projects unit is enabled or not.",
						},
						"has_pull_requests": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the pull requests unit is enabled or not.",
						},
						"has_releases": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the releases unit is enabled or not.",
						},
						"has_wiki": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the wiki unit is enabled or not.",
						},
						"html_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The HTTP URL of the repository.",
						},
						"id": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The identifier of the repository.",
						},
						"ignore_whitespace_conflicts": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether whitespaces are ignored when detecting pull request conflicts or not.",
						},
						"internal": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether this is an internal repository or not.",
						},
						"internal_tracker": schema.SingleNestedAttribute{
							Attributes: map[string]schema.Attribute{
								"allow_only_contributors_to_track_time": schema.BoolAttribute{
									Computed:            true,
									MarkdownDescription: "Whether only contributors are allowed to track time on issues or not.",
								},
								"enable_issue_dependencies": schema.BoolAttribute{
									Computed:            true,
									MarkdownDescription: "Whether issue dependencies are enabled or not.",
								},
								"enable_time_tracker": schema.BoolAttribute{
									Computed:            true,
									MarkdownDescription: "Whether time tracking is enabled or not.",
								},
							},
							Computed: true,
						},
						"language": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The main programming language used in the repository.",
						},
						"languages_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The URL to the languages page.",
						},
						"link": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The link.",
						},
						"mirror": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is a mirror or not.",
						},
						"mirror_interval": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The mirror time interval.",
						},
						"mirror_updated": schema.StringAttribute{
							Computed:            true,
							CustomType:          timetypes.RFC3339Type{},
							MarkdownDescription: "The datetime at which the mirror was last updated.",
						},
						"name": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The name of the repository.",
						},
						"object_format_name": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The name of the object format.",
						},
						"open_issues_count": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of open issues.",
						},
						"open_pr_counter": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of open pull requests.",
						},
						"original_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The original URL.",
						},
						"owner": schema.SingleNestedAttribute{
							Attributes: userSchemaAttributes,
							Computed:   true,
						},
						//"parent"
						"permissions": schema.SingleNestedAttribute{
							Attributes: permissionSchemaAttributes,
							Computed:   true,
						},
						"private": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is private or not.",
						},
						"release_counter": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of releases.",
						},
						"repo_transfer": schema.SingleNestedAttribute{
							Attributes: map[string]schema.Attribute{
								"description": schema.StringAttribute{
									Computed:            true,
									MarkdownDescription: "A description string.",
								},
								"doer": schema.SingleNestedAttribute{
									Attributes: userSchemaAttributes,
									Computed:   true,
								},
								"recipient": schema.SingleNestedAttribute{
									Attributes: userSchemaAttributes,
									Computed:   true,
								},
								"teams": teamSchemaAttributes,
							},
							Computed: true,
						},
						"size": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The size of the repository in KiB.",
						},
						"ssh_url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The SSH URL.",
						},
						"stars_count": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of stars.",
						},
						"template": schema.BoolAttribute{
							Computed:            true,
							MarkdownDescription: "Whether the repository is a template or not.",
						},
						"topics": schema.ListAttribute{
							Computed:            true,
							ElementType:         types.StringType,
							MarkdownDescription: "The list of topics.",
						},
						"updated_at": schema.StringAttribute{
							Computed:            true,
							CustomType:          timetypes.RFC3339Type{},
							MarkdownDescription: "The datetime at which the repository was last updated.",
						},
						"url": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The API URL.",
						},
						"watchers_count": schema.Int64Attribute{
							Computed:            true,
							MarkdownDescription: "The number of watchers.",
						},
						"website": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The website URL.",
						},
						"wiki_branch": schema.StringAttribute{
							Computed:            true,
							MarkdownDescription: "The name of the default branch of the wiki.",
						},
					},
				},
			},
		},
		MarkdownDescription: "Use this data source to retrieve information about existing forgejo repositories.",
	}
}

func (d *RepositoriesDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
	d.client, _ = req.ProviderData.(*client.Client)
}

func (d *RepositoriesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
	var data RepositoriesDataSourceModel
	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
	if resp.Diagnostics.HasError() {
		return
	}
	repositories, err := d.client.RepositoriesList(ctx)
	if err != nil {
		resp.Diagnostics.AddError("ListRepositories", fmt.Sprintf("failed to list repositories: %s", err))
		return
	}
	repositoriesList := make([]RepositoryDataSourceModel, len(repositories))
	for i, repository := range repositories {
		repositoriesList[i] = RepositoryDataSourceModel{
			AllowFastForwardOnlyMerge:     types.BoolValue(repository.AllowFastForwardOnlyMerge),
			AllowMergeCommits:             types.BoolValue(repository.AllowMergeCommits),
			AllowRebase:                   types.BoolValue(repository.AllowRebase),
			AllowRebaseExplicit:           types.BoolValue(repository.AllowRebaseExplicit),
			AllowRebaseUpdate:             types.BoolValue(repository.AllowRebaseUpdate),
			AllowSquashMerge:              types.BoolValue(repository.AllowSquashMerge),
			ArchivedAt:                    timetypes.NewRFC3339TimeValue(repository.ArchivedAt),
			Archived:                      types.BoolValue(repository.Archived),
			AvatarUrl:                     types.StringValue(repository.AvatarUrl),
			CloneUrl:                      types.StringValue(repository.CloneUrl),
			CreatedAt:                     timetypes.NewRFC3339TimeValue(repository.CreatedAt),
			DefaultAllowMaintainerEdit:    types.BoolValue(repository.DefaultAllowMaintainerEdit),
			DefaultBranch:                 types.StringValue(repository.DefaultBranch),
			DefaultDeleteBranchAfterMerge: types.BoolValue(repository.DefaultDeleteBranchAfterMerge),
			DefaultMergeStyle:             types.StringValue(repository.DefaultMergeStyle),
			DefaultUpdateStyle:            types.StringValue(repository.DefaultUpdateStyle),
			Description:                   types.StringValue(repository.Description),
			Empty:                         types.BoolValue(repository.Empty),
			ExternalTracker:               nil,
			ExternalWiki:                  nil,
			Fork:                          types.BoolValue(repository.Fork),
			ForksCount:                    types.Int64Value(repository.ForksCount),
			FullName:                      types.StringValue(repository.FullName),
			GloballyEditableWiki:          types.BoolValue(repository.GloballyEditableWiki),
			HasActions:                    types.BoolValue(repository.HasActions),
			HasIssues:                     types.BoolValue(repository.HasIssues),
			HasPackages:                   types.BoolValue(repository.HasPackages),
			HasProjects:                   types.BoolValue(repository.HasProjects),
			HasPullRequests:               types.BoolValue(repository.HasPullRequests),
			HasReleases:                   types.BoolValue(repository.HasReleases),
			HasWiki:                       types.BoolValue(repository.HasWiki),
			HtmlUrl:                       types.StringValue(repository.HtmlUrl),
			Id:                            types.Int64Value(repository.Id),
			IgnoreWhitespaceConflicts:     types.BoolValue(repository.IgnoreWhitespaceConflicts),
			Internal:                      types.BoolValue(repository.Internal),
			InternalTracker:               nil,
			Language:                      types.StringValue(repository.Language),
			LanguagesUrl:                  types.StringValue(repository.LanguagesUrl),
			Link:                          types.StringValue(repository.Link),
			Mirror:                        types.BoolValue(repository.Mirror),
			MirrorInterval:                types.StringValue(repository.MirrorInterval),
			MirrorUpdated:                 timetypes.NewRFC3339TimeValue(repository.MirrorUpdated),
			Name:                          types.StringValue(repository.Name),
			ObjectFormatName:              types.StringValue(repository.ObjectFormatName),
			OpenIssuesCount:               types.Int64Value(repository.OpenIssuesCount),
			OpenPrCounter:                 types.Int64Value(repository.OpenPrCounter),
			OriginalUrl:                   types.StringValue(repository.OriginalUrl),
			Owner:                         nil,
			Permissions:                   nil,
			Private:                       types.BoolValue(repository.Private),
			ReleaseCounter:                types.Int64Value(repository.ReleaseCounter),
			RepoTransfer:                  nil,
			Size:                          types.Int64Value(repository.Size),
			SshUrl:                        types.StringValue(repository.SshUrl),
			StarsCount:                    types.Int64Value(repository.StarsCount),
			Template:                      types.BoolValue(repository.Template),
			Topics:                        make([]types.String, len(repository.Topics)),
			UpdatedAt:                     timetypes.NewRFC3339TimeValue(repository.UpdatedAt),
			Url:                           types.StringValue(repository.Url),
			WatchersCount:                 types.Int64Value(repository.WatchersCount),
			Website:                       types.StringValue(repository.Website),
			WikiBranch:                    types.StringValue(repository.WikiBranch),
		}
		if repository.ExternalTracker != nil {
			repositoriesList[i].ExternalTracker = &RepositoryExternalTrackerDataSourceModel{
				Description:   types.StringValue(repository.ExternalTracker.Description),
				Format:        types.StringValue(repository.ExternalTracker.Format),
				RegexpPattern: types.StringValue(repository.ExternalTracker.RegexpPattern),
				Style:         types.StringValue(repository.ExternalTracker.Style),
				Url:           types.StringValue(repository.ExternalTracker.Url),
			}
		}
		if repository.ExternalWiki != nil {
			repositoriesList[i].ExternalWiki = &RepositoryExternalWikiDataSourceModel{
				Description: types.StringValue(repository.ExternalTracker.Description),
				Url:         types.StringValue(repository.ExternalTracker.Url),
			}
		}
		if repository.InternalTracker != nil {
			repositoriesList[i].InternalTracker = &RepositoryInternalTrackerDataSourceModel{
				AllowOnlyContributorsToTrackTime: types.BoolValue(repository.InternalTracker.AllowOnlyContributorsToTrackTime),
				EnableIssueDependencies:          types.BoolValue(repository.InternalTracker.EnableIssueDependencies),
				EnableTimeTracker:                types.BoolValue(repository.InternalTracker.EnableTimeTracker),
			}
		}
		if repository.Owner != nil {
			repositoriesList[i].Owner = populateUserDataSourceModel(repository.Owner)
		}
		if repository.Permissions != nil {
			repositoriesList[i].Permissions = &PermissionDataSourceModel{
				Admin: types.BoolValue(repository.Permissions.Admin),
				Pull:  types.BoolValue(repository.Permissions.Pull),
				Push:  types.BoolValue(repository.Permissions.Push),
			}
		}
		if repository.RepoTransfer != nil {
			repositoriesList[i].RepoTransfer = &RepositoryTransferDataSourceModel{
				Description: types.StringValue(repository.RepoTransfer.Description),
				Doer:        populateUserDataSourceModel(repository.RepoTransfer.Doer),
				Recipient:   populateUserDataSourceModel(repository.RepoTransfer.Recipient),
				Teams:       make([]TeamDataSourceModel, len(repository.RepoTransfer.Teams)),
			}
			for j, team := range repository.RepoTransfer.Teams {
				repositoriesList[i].RepoTransfer.Teams[j] = *populateTeamDataSourceModel(&team)
			}
		}
		for j, topic := range repository.Topics {
			repositoriesList[i].Topics[j] = types.StringValue(topic)
		}
	}
	data.Elements = repositoriesList
	resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}