package onescli

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

	onesapi "github.com/tidbcloud/devops/pkg/infra/clients/onescli/api"
	"github.com/tidbcloud/devops/pkg/infra/log"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
	"github.com/tidbcloud/devops/pkg/infra/utils/test"

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

func TestOnesClient(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "OnesClient Suite", test.ReporterConfig())
}

var _ = Describe("[OnesClient]", func() {
	var cli OnesClient
	var fw = test.Framework()
	var ctx context.Context

	BeforeEach(func() {
		ctx = log.NewContext(context.Background(), fw.Logger)

		var err error
		token := os.Getenv("ONES_TOKEN")
		teamID := os.Getenv("ONES_TEAMID")

		cli, err = newOnesClient("sz.ones.cn", token, teamID)
		Expect(err).To(BeNil())
	})

	Describe("[Issue]", func() {
		PIt("get a issue", func() {
			id := "OPS-1"
			issue, err := cli.GetIssue(ctx, id)
			Expect(err).To(BeNil())
			Expect(issue).NotTo(BeNil())
			os.WriteFile(fmt.Sprintf("%s.json", id), []byte(test.MarshalIndentOrDie(issue)), 0600)
		})

		PIt("list issues", func() {
			resp, err := cli.SearchIssues(ctx, SearchIssuesParam{
				ProjectIs: pointer.Pointer("DM"),
			})
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(resp))
		})

		PIt("list fields", func() {
			resp, err := cli.(*client).ListIssueFields(ctx)
			Expect(err).To(BeNil())
			fmt.Println(test.MarshalIndentOrDie(resp))
		})

		PIt("update issue status", func() {
			err := cli.(*client).UpdateIssueStatus(ctx, "OPS-1", "READY FOR RELEASE")
			Expect(err).To(BeNil())
		})

		PIt("create issue", func() {
			req := onesapi.CreateIssueRequest{
				Title:     "Test Create Issue",
				Project:   "DM",
				IssueType: onesapi.IssueTypeRelease,
				Assignee:  "sihao.yu@pingcap.cn",
			}
			id, err := cli.(*client).CreateIssue(ctx, req)
			fmt.Println(id)
			Expect(err).To(BeNil())
		})
	})

	Describe("[User]", func() {
		PIt("get a user", func() {
			users, err := cli.SearchUser(ctx, "sihao.yu@pingcap.cn")
			fmt.Println(test.MarshalIndentOrDie(users))
			Expect(err).To(BeNil())
			Expect(users).NotTo(BeNil())
		})
	})

	Describe("[Scripts]", func() {
		Describe("[Ones]", func() {
			PIt("Create release for future", func() {
				start := time.Now().AddDate(0, 1, 0)
				end := start.AddDate(1, 0, 0) // one year later

				project := "DM"
				assignee := "sihao.yu@pingcap.cn"

				releaseDate := time.Date(start.Year(), start.Month(), start.Day(), 0, 0, 0, 0, start.Location())
				for releaseDate.Weekday() != time.Tuesday {
					releaseDate = releaseDate.AddDate(0, 0, 1)
				}

				for !releaseDate.After(end) {
					title := fmt.Sprintf("release-%s", releaseDate.Format("20060102"))
					req := onesapi.CreateIssueRequest{
						Title:     title,
						Project:   project,
						IssueType: onesapi.IssueTypeRelease,
						Assignee:  assignee,
					}

					id, err := cli.(*client).CreateIssue(ctx, req)
					Expect(err).To(BeNil())
					fmt.Printf("created issue: %s (%s)\n", id, title)

					releaseDate = releaseDate.AddDate(0, 0, 7)
				}
			})
		})
	})

})
