package spu

import (
	"testing"

	"github.com/smartystreets/goconvey/convey"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
)

func TestSelector(t *testing.T) {
	t.Parallel()

	convey.Convey("Test_selector", t, func() {
		labels := Labels{
			globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU: "33",
			globaldedicatedv1.Sku_Condition_REGION:         "us-west-2",
			globaldedicatedv1.Sku_Condition_TENANT:         "123",
			globaldedicatedv1.Sku_Condition_PROVIDER:       "aws",
		}

		convey.Convey("range_operator", func() {
			_, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU,
				globaldedicatedv1.Sku_Condition_RANGE,
				[]string{"21"},
			)
			convey.So(err, convey.ShouldBeError)

			_, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU,
				globaldedicatedv1.Sku_Condition_RANGE,
				[]string{"21", "456", "789"},
			)
			convey.So(err, convey.ShouldBeError)

			_, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU,
				globaldedicatedv1.Sku_Condition_RANGE,
				[]string{"21", "2"},
			)
			convey.So(err, convey.ShouldBeError)

			selector, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU,
				globaldedicatedv1.Sku_Condition_RANGE,
				[]string{"21", "45"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok := selector.Matches(labels)
			convey.So(ok, convey.ShouldBeTrue)

			selector, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TIKV_TOTAL_CPU,
				globaldedicatedv1.Sku_Condition_RANGE,
				[]string{"10", "31"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok = selector.Matches(labels)
			convey.So(ok, convey.ShouldBeFalse)
		})

		convey.Convey("in", func() {
			_, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_IN,
				[]string{},
			)
			convey.So(err, convey.ShouldBeError)

			selector, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_IN,
				[]string{"1", "123"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok := selector.Matches(labels)
			convey.So(ok, convey.ShouldBeTrue)

			selector, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_IN,
				[]string{"1", "2"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok = selector.Matches(labels)
			convey.So(ok, convey.ShouldBeFalse)
		})

		convey.Convey("not in", func() {
			_, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NOTIN,
				[]string{},
			)
			convey.So(err, convey.ShouldBeError)

			selector, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NOTIN,
				[]string{"1", "2"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok := selector.Matches(labels)
			convey.So(ok, convey.ShouldBeTrue)

			selector, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NOTIN,
				[]string{"1", "123"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok = selector.Matches(labels)
			convey.So(ok, convey.ShouldBeFalse)
		})

		convey.Convey("equals", func() {
			_, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_EQ,
				[]string{},
			)
			convey.So(err, convey.ShouldBeError)

			_, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_EQ,
				[]string{"123", "456"},
			)
			convey.So(err, convey.ShouldBeError)

			selector, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_EQ,
				[]string{"123"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok := selector.Matches(labels)
			convey.So(ok, convey.ShouldBeTrue)

			selector, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_EQ,
				[]string{"1"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok = selector.Matches(labels)
			convey.So(ok, convey.ShouldBeFalse)
		})

		convey.Convey("not equals", func() {
			_, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NE,
				[]string{},
			)
			convey.So(err, convey.ShouldBeError)

			_, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NE,
				[]string{"123", "456"},
			)
			convey.So(err, convey.ShouldBeError)

			selector, err := NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NE,
				[]string{"1"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok := selector.Matches(labels)
			convey.So(ok, convey.ShouldBeTrue)

			selector, err = NewSelector(
				globaldedicatedv1.Sku_Condition_TENANT,
				globaldedicatedv1.Sku_Condition_NE,
				[]string{"123"},
			)
			convey.So(err, convey.ShouldBeNil)
			ok = selector.Matches(labels)
			convey.So(ok, convey.ShouldBeFalse)
		})
	})
}
