package feature

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/dataflow-service/internal/config"
)

func TestGetAllowFeatures(t *testing.T) {
	const testFeatureA = "test-feature-a"
	const testFeatureB = "test-feature-b"
	config.Global().ServerConfig.FeaturesSwitchers.PublicFeatures = []string{testFeatureA}
	config.Global().ServerConfig.FeaturesSwitchers.FeaturesAllowList = map[string]config.AllowListMatcher{
		PiTR: {
			TenantID:  []string{"1", "2"},
			ProjectID: []string{"1", "2"},
			ClusterID: []string{"1", "2"},
		},
		DualRegionBR: {
			TenantID:  []string{"2", "3"},
			ProjectID: []string{"2", "3"},
			ClusterID: []string{"2", "3"},
		},
		SkipImportVildation: {
			TenantID: []string{"100"},
		},
		AllowMultiImportJobs: {
			ProjectID: []string{"100", "200"},
		},
		SkipCdcPitrCheckWhenImport: {
			TenantID: []string{"1369847559691367424"},
		},
	}
	config.Global().ServerConfig.FeaturesSwitchers.EnabledFeatureByDeployment = map[string]config.DeploymentMatcher{
		DM: {
			Regions:   []string{"us-west-2"},
			Providers: []string{"eks"},
		},
		MaintainingDMJobs: {
			Regions:   []string{"us-west1"},
			Providers: []string{"gcp"},
		},
	}

	// enabled by PublicFeatures
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 11, "xx", "xx"),
		[]string{testFeatureA})
	// enabled by EnabledFeatureByDeployment: all property must satisfy
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 11, "us-west-2", "aaa"),
		[]string{testFeatureA})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 11, "aaa", "eks"),
		[]string{testFeatureA})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 11, "us-west-2", "eks"),
		[]string{testFeatureA, DM})
	// enabled by tenant id in FeaturesAllowList without cluster property
	assert.True(t, IsFeatureEnabled(PiTR, 1, 11, 11, "us-west-2", "eks"))
	assert.True(t, IsFeatureEnabled(SkipImportVildation, 100, 0, 0, "", ""))
	assert.False(t, IsFeatureEnabled(SkipImportVildation, 200, 0, 0, "", ""))
	assert.True(t, IsFeatureEnabled(AllowMultiImportJobs, 1, 200, 2, "", ""))
	assert.True(t, IsFeatureEnabled(MaintainingDMJobs, 0, 0, 0, "us-west1", "gcp"))
	assert.True(t, IsFeatureEnabled(MaintainingDMJobs, 100, 10, 1, "us-west1", "gcp"))
	assert.False(t, IsFeatureEnabled(MaintainingDMJobs, 0, 0, 0, "us-west1", "eks"))
	assert.False(t, IsFeatureEnabled(MaintainingDMJobs, 0, 0, 0, "us-west1", ""))
	assert.False(t, IsFeatureEnabled(MaintainingDMJobs, 0, 0, 0, "", "gcp"))
	assert.True(t, IsFeatureEnabled(SkipCdcPitrCheckWhenImport, 1369847559691367424, 200, 2, "", ""))

	assert.ElementsMatch(t, GetEnabledFeatures(1, 11, 11, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DM})
	assert.ElementsMatch(t, GetEnabledFeatures(2, 11, 11, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DualRegionBR, DM})
	// enabled by project id in FeaturesAllowList without cluster property
	assert.ElementsMatch(t, GetEnabledFeatures(11, 1, 11, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DM})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 2, 11, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DualRegionBR, DM})
	// enabled by cluster id in FeaturesAllowList without cluster property
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 1, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DM})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 2, "us-west-2", "eks"),
		[]string{testFeatureA, PiTR, DualRegionBR, DM})
	// not match by any FeaturesAllowList
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 11, "us-west-2", "eks"),
		[]string{testFeatureA, DM})

	config.Global().ServerConfig.FeaturesSwitchers.FeaturesAllowList[testFeatureB] = config.AllowListMatcher{
		TenantID:  []string{"3", "4"},
		ProjectID: []string{"3", "4"},
		ClusterID: []string{"3", "4"},
		DeploymentMatcher: &config.DeploymentMatcher{
			Regions:   []string{"us-west-1", "us-west-2"},
			Providers: []string{"eks", "aws"},
		},
	}
	// enabled by tenant id in FeaturesAllowList with cluster property, all cluster property must satisfy
	assert.ElementsMatch(t, GetEnabledFeatures(3, 11, 11, "us-west-1", "eks"),
		[]string{testFeatureA, DualRegionBR, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(4, 11, 11, "us-west-2", "eks"),
		[]string{testFeatureA, DM, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(4, 11, 11, "us-west-2", "aws"),
		[]string{testFeatureA, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(4, 11, 11, "xxx", "aws"),
		[]string{testFeatureA})
	// enabled by project id in FeaturesAllowList with cluster property, all cluster property must satisfy
	assert.ElementsMatch(t, GetEnabledFeatures(11, 3, 11, "us-west-1", "eks"),
		[]string{testFeatureA, DualRegionBR, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 4, 11, "us-west-2", "eks"),
		[]string{testFeatureA, DM, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 4, 11, "us-west-2", "aws"),
		[]string{testFeatureA, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 4, 11, "xxx", "aws"),
		[]string{testFeatureA})
	// enabled by cluster id in FeaturesAllowList with cluster property, all cluster property must satisfy
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 3, "us-west-1", "eks"),
		[]string{testFeatureA, DualRegionBR, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 4, "us-west-2", "eks"),
		[]string{testFeatureA, DM, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 4, "us-west-2", "aws"),
		[]string{testFeatureA, testFeatureB})
	assert.ElementsMatch(t, GetEnabledFeatures(11, 11, 4, "xxx", "aws"),
		[]string{testFeatureA})
}
