package githubcli

import (
	"context"
	"fmt"
	"os"
	"testing"

	"github.com/tidbcloud/devops/pkg/infra/config"
	"github.com/tidbcloud/devops/pkg/infra/utils/test"

	ginkgo "github.com/onsi/ginkgo/v2"
	. "github.com/onsi/gomega"
	"github.com/shurcooL/githubv4"
)

func TestGithubClient(t *testing.T) {
	RegisterFailHandler(ginkgo.Fail)
	ginkgo.RunSpecs(t, "Github Client Suite", test.ReporterConfig())
}

// Default to pending, run it if you want to test client.
var _ = ginkgo.Describe("[GithubClient]", func() {
	var gh *GithubClient

	ginkgo.BeforeEach(func() {
		var err error
		token := os.Getenv("GITHUB_TOKEN")

		conf := &config.RootConfig{}
		conf.Clients.Github.Token = token
		gh, err = NewGithubClient(conf)
		Expect(err).To(BeNil())
	})

	ginkgo.Context("[PullRequestsService]", func() {
		var ctx context.Context
		var svc PullRequestsService
		var owner = "tidbcloud"
		var repo = "app-delivery"

		ginkgo.BeforeEach(func() {
			ctx = context.Background()
			svc = gh.PullRequest
		})

		ginkgo.PIt("get a existing pull request", func() {
			pr, err := svc.Get(ctx, owner, repo, 1)
			Expect(err).To(BeNil())

			fmt.Println(test.MarshalIndentOrDie(pr))
		})

		ginkgo.PIt("get a non-existing pull request", func() {
			_, err := svc.Get(ctx, owner, repo, 1500)
			Expect(err).To(HaveOccurred())
			fmt.Println(err)
		})

		ginkgo.PIt("query pull requests", func() {
			opt := ListPullRequestOption{
				Labels: []string{"release-0.9"},
				Pager:  Pager{PerPage: 5},
			}
			result, err := svc.List(ctx, owner, repo, opt)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(result))

			if result.Page.HasNextPage {
				opt.Pager.Cursor = result.Page.EndCursor
				result, err = svc.List(ctx, owner, repo, opt)
				Expect(err).To(BeNil())
				fmt.Println(test.MarshalIndentOrDie(result))
			}
		})

		ginkgo.PIt("approve a pr", func() {
			comment := ``

			prr, err := svc.Approve(ctx, owner, repo, 56867, comment)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(prr))
		})

		ginkgo.PIt("merge a pull request", func() {
			prResult, err := svc.Merge(ctx, owner, repo, 20, githubv4.PullRequestMergeMethodSquash)
			Expect(err).To(BeNil())

			fmt.Println(test.MarshalIndentOrDie(prResult))
		})

		ginkgo.PIt("create a comment", func() {
			comment, err := svc.AddComment(ctx, owner, repo, 20, "test comment")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(comment))
		})

	})

	ginkgo.Context("[ReleaseService]", func() {
		var ctx context.Context
		var svc ReleaseService
		var owner = "tidbcloud"
		var repo = "infra-provider"

		ginkgo.BeforeEach(func() {
			ctx = context.Background()
			svc = gh.Release
		})

		ginkgo.PIt("get", func() {
			rl, err := svc.Get(ctx, owner, repo, "new-arch/v0.72.0")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(rl))
		})

		ginkgo.PIt("list", func() {
			opt := ListReleaseOption{
				Pager: Pager{},
			}
			rl, err := svc.List(ctx, owner, repo, opt)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(rl))
		})

		ginkgo.PIt("diff by tag", func() {
			prs, err := svc.Diff(ctx, owner, repo, "v0.9.0", "v0.8.1")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(prs))
			fmt.Println(len(prs))
		})
	})

	ginkgo.Context("[RepositoryService]", func() {
		var ctx context.Context
		var svc RepositoryService
		var owner = "tidbcloud"
		var repo = "devops"

		ginkgo.BeforeEach(func() {
			ctx = context.Background()
			svc = gh.Repository
		})

		ginkgo.PIt("get", func() {
			repo, err := svc.Get(ctx, owner, repo)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(repo))
		})

		ginkgo.PIt("list", func() {
			opt := ListRepositoryOption{
				Pager: Pager{
					PerPage: 5,
				},
			}
			result, err := svc.List(ctx, owner, opt)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(result))

			if result.Page.HasNextPage {
				opt.Pager.Cursor = result.Page.EndCursor
				result, err = svc.List(ctx, owner, opt)
				Expect(err).To(BeNil())
				fmt.Println(test.MarshalIndentOrDie(result))
			}
		})

		ginkgo.PIt("get label", func() {
			label, err := svc.GetLabel(ctx, owner, repo, "bug")
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(label))
		})

		ginkgo.PIt("list labels", func() {
			opt := ListLabelOption{}
			labels, err := svc.ListLabels(ctx, owner, repo, opt)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(labels))
		})
	})
})
