package plugin

import (
	"testing"

	. "github.com/onsi/gomega"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func TestScore(t *testing.T) {
	cases := map[string]struct {
		acctCount int
		input     func(sctx *SchedContext, network *cloudv1.Network, accts []*cloudv1.Account)
		expect    func(*WithT, []AcctScore, *ActionResult)
	}{
		"no account": {
			acctCount: 0,
			input:     func(sctx *SchedContext, network *cloudv1.Network, accts []*cloudv1.Account) {},
			expect: func(g *WithT, scores []AcctScore, result *ActionResult) {
				g.Expect(result).Should(Equal(NewActionResult(Success)))
				g.Expect(scores).Should(BeEmpty())
			},
		},
		"no default account": {
			acctCount: 3,
			input:     func(sctx *SchedContext, network *cloudv1.Network, accts []*cloudv1.Account) {},
			expect: func(g *WithT, scores []AcctScore, result *ActionResult) {
				g.Expect(result).Should(Equal(NewActionResult(Success)))
				expectScores := []AcctScore{
					{
						AccountName: "account-0",
						Score:       0,
					},
					{
						AccountName: "account-1",
						Score:       0,
					},
					{
						AccountName: "account-2",
						Score:       0,
					},
				}
				g.Expect(scores).Should(Equal(expectScores))
			},
		},
		"one default account": {
			acctCount: 3,
			input: func(sctx *SchedContext, network *cloudv1.Network, accts []*cloudv1.Account) {
				accts[1].Annotations = map[string]string{}
				accts[1].Annotations[defaultAcctAnno] = "true"
			},
			expect: func(g *WithT, scores []AcctScore, result *ActionResult) {
				g.Expect(result).Should(Equal(NewActionResult(Success)))
				expectScores := []AcctScore{
					{
						AccountName: "account-0",
						Score:       0,
					},
					{
						AccountName: "account-1",
						Score:       100,
					},
					{
						AccountName: "account-2",
						Score:       0,
					},
				}
				g.Expect(scores).Should(Equal(expectScores))
			},
		},
	}

	for name, c := range cases {
		t.Run(name, func(t *testing.T) {
			g := NewGomegaWithT(t)

			sctx := &SchedContext{}
			network := &cloudv1.Network{}
			accts := accounts(c.acctCount)

			c.input(sctx, network, accts)

			p := &defaultAccount{}
			scores, result := p.Score(sctx, network, accts)

			c.expect(g, scores, result)
		})
	}
}
