package cvt

import (
	"testing"
	"time"

	ent "github.com/tidbcloud/devops/entity/github"
	"github.com/tidbcloud/devops/models/base"
	mod "github.com/tidbcloud/devops/models/github"
	"github.com/tidbcloud/devops/pkg/infra/utils/test"

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

func TestRepo(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Github Converter Suite")
}

var _ = Describe("[Github Repo Converter]", func() {

	Describe("PullRequest", func() {
		Context("[Model To Entity]", func() {
			It("should not miss fields when converting", func() {
				time := time.Now()

				// every fields MUST be set as a non zero value
				org := &mod.GithubPullRequest{
					ID:        base.ID(1),
					Location:  "tidbcloud/devops#100",
					Owner:     "tidbcloud",
					Repo:      "devops",
					Number:    100,
					Title:     "DevOps PR Title",
					Author:    "KanShiori",
					State:     "Merged",
					CreatedAt: time,
					UpdatedAt: time,
				}
				exp := &ent.PullRequestInDB{
					ID:        1,
					Location:  "tidbcloud/devops#100",
					Owner:     "tidbcloud",
					Repo:      "devops",
					Number:    100,
					Title:     "DevOps PR Title",
					Author:    "KanShiori",
					State:     "Merged",
					CreatedAt: time.Unix(),
					UpdatedAt: time.Unix(),
				}

				Expect(test.CheckNonZeroValue(org, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")

				got := m2e{}.PullRequest(org)
				Expect(test.CheckNonZeroValue(got, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")
				Expect(test.IsEqual(exp, got)).To(BeNil())
			})

		})

		Context("[Entity To Model]", func() {
			It("should not miss fields when converting", func() {
				time := *test.ParseTimeOrDie(time.DateTime, "2023-06-12 11:00:00")

				// every fields MUST be set as a non zero value
				org := &ent.PullRequestInDB{
					ID:        1,
					Location:  "tidbcloud/devops#100",
					Owner:     "tidbcloud",
					Repo:      "devops",
					Number:    100,
					Title:     "DevOps PR Title",
					Author:    "KanShiori",
					State:     "Merged",
					CreatedAt: time.Unix(),
					UpdatedAt: time.Unix(),
				}
				exp := &mod.GithubPullRequest{
					ID:        base.ID(1),
					Location:  "tidbcloud/devops#100",
					Owner:     "tidbcloud",
					Repo:      "devops",
					Number:    100,
					Title:     "DevOps PR Title",
					Author:    "KanShiori",
					State:     "Merged",
					CreatedAt: time,
					UpdatedAt: time,
				}
				ignoredFields := []string{}

				Expect(test.CheckNonZeroValue(org, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")

				got := e2m{}.PullRequest(org)
				Expect(test.CheckNonZeroValue(got, ignoredFields)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")
				Expect(test.IsEqual(exp, got)).To(BeNil())
			})
		})
	})

	Describe("Repository", func() {
		Context("[Model To Entity]", func() {
			It("should not miss fields when converting", func() {
				time := time.Now()
				// every fields MUST be set as a non zero value
				org := &mod.GithubRepository{
					ID:        base.ID(1),
					Location:  "tidbcloud/devops",
					Owner:     "tidbcloud",
					Name:      "devops",
					UpdatedAt: time,
					PushedAt:  time,
				}
				exp := &ent.RepositoryInDB{
					ID:        1,
					Location:  "tidbcloud/devops",
					Owner:     "tidbcloud",
					Name:      "devops",
					UpdatedAt: time.Unix(),
					PushedAt:  time.Unix(),
				}

				Expect(test.CheckNonZeroValue(org, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")

				got := m2e{}.Repository(org)
				Expect(test.CheckNonZeroValue(got, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")
				Expect(test.IsEqual(exp, got)).To(BeNil())
			})

		})

		Context("[Entity To Model]", func() {
			It("should not miss fields when converting", func() {
				time := *test.ParseTimeOrDie(time.DateTime, "2023-06-12 11:00:00")
				org := &ent.RepositoryInDB{
					ID:        1,
					Location:  "tidbcloud/devops",
					Owner:     "tidbcloud",
					Name:      "devops",
					UpdatedAt: time.Unix(),
					PushedAt:  time.Unix(),
				}
				exp := &mod.GithubRepository{
					ID:        base.ID(1),
					Location:  "tidbcloud/devops",
					Owner:     "tidbcloud",
					Name:      "devops",
					UpdatedAt: time,
					PushedAt:  time,
				}
				ignoredFields := []string{}

				Expect(test.CheckNonZeroValue(org, nil)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")

				got := e2m{}.Repository(org)
				Expect(test.CheckNonZeroValue(got, ignoredFields)).To(BeNil(), "some fields missed, maybe added new fields but forgot to update converter")
				Expect(test.IsEqual(exp, got)).To(BeNil())
			})
		})
	})
})
