package case_driver

import (
	"github.com/elliotchance/pie/v2"
	"github.com/tidbcloud/dataflow-service-e2e/cases"
	"github.com/tidbcloud/dataflow-service-e2e/cases/premium/changefeed"
	"github.com/tidbcloud/dataflow-service-e2e/cases/premium/dm"
	"github.com/tidbcloud/dataflow-service-e2e/cases/premium/import_data"
	"github.com/tidbcloud/dataflow-service-e2e/internal/config"
	. "github.com/tidbcloud/dataflow-service-e2e/internal/model"
)

func RegisterPremiumCases() {
	// add cases
	awsKafkaChangefeedSmokeCase := changefeed.NewKafkaChangefeedSmokeCase(AWS)
	alicloudKafkaChangefeedSmokeCase := changefeed.NewKafkaChangefeedSmokeCase(AliCloud)
	gcpKafkaChangefeedSmokeCase := changefeed.NewKafkaChangefeedSmokeCase(GCP)
	azureKafkaChangefeedSmokeCase := changefeed.NewKafkaChangefeedSmokeCase(AZURE)
	addCases(awsKafkaChangefeedSmokeCase, alicloudKafkaChangefeedSmokeCase,
		gcpKafkaChangefeedSmokeCase, azureKafkaChangefeedSmokeCase)

	awsKafkaKernelConfiguration := changefeed.NewKafkaChangefeedKernelConfigurationCase(AWS)
	alicloudKafkaKernelConfiguration := changefeed.NewKafkaChangefeedKernelConfigurationCase(AliCloud)
	gcpKafkaKernelConfiguration := changefeed.NewKafkaChangefeedKernelConfigurationCase(GCP)
	azureKafkaKernelConfiguration := changefeed.NewKafkaChangefeedKernelConfigurationCase(AZURE)
	addCases(awsKafkaKernelConfiguration, alicloudKafkaKernelConfiguration, gcpKafkaKernelConfiguration, azureKafkaKernelConfiguration)

	awsKafkaPrivateLink := changefeed.NewKafkaPrivateLinkCase(AWS)
	gcpKafkaPrivateLink := changefeed.NewKafkaPrivateLinkCase(GCP)
	azureKafkaPrivateLink := changefeed.NewKafkaPrivateLinkCase(AZURE)
	alicloudKafkaPrivateLink := changefeed.NewKafkaPrivateLinkCase(AliCloud)
	addCases(awsKafkaPrivateLink, gcpKafkaPrivateLink, azureKafkaPrivateLink, alicloudKafkaPrivateLink)

	awsTestConnection := changefeed.NewKafkaTestConnectionCase(AWS)
	gcpTestConnection := changefeed.NewKafkaTestConnectionCase(GCP)
	azureTestConnection := changefeed.NewKafkaTestConnectionCase(AZURE)
	alicloudTestConnection := changefeed.NewKafkaTestConnectionCase(AliCloud)
	addCases(awsTestConnection, azureTestConnection, gcpTestConnection, alicloudTestConnection)

	awsKafkaValidateChangefeedParams := changefeed.NewKafkaValidateChangefeedParamsCase(AWS)
	gcpKafkaValidateChangefeedParams := changefeed.NewKafkaValidateChangefeedParamsCase(GCP)
	azureKafkaValidateChangefeedParams := changefeed.NewKafkaValidateChangefeedParamsCase(AZURE)
	alicloudKafkaValidateChangefeedParams := changefeed.NewKafkaValidateChangefeedParamsCase(AliCloud)
	addCases(awsKafkaValidateChangefeedParams, gcpKafkaValidateChangefeedParams, azureKafkaValidateChangefeedParams, alicloudKafkaValidateChangefeedParams)

	azureKafkaAvroChangefeedCase := changefeed.NewKafkaAvroChangefeedCase(AZURE)
	addCases(azureKafkaAvroChangefeedCase)

	awsScaleChangefeedCase := changefeed.NewScaleChangefeedCase(AWS)
	gcpScaleChangefeedCase := changefeed.NewScaleChangefeedCase(GCP)
	azureScaleChangefeedCase := changefeed.NewScaleChangefeedCase(AZURE)
	alicloudScaleChangefeedCase := changefeed.NewScaleChangefeedCase(AliCloud)
	addCases(awsScaleChangefeedCase, gcpScaleChangefeedCase, azureScaleChangefeedCase, alicloudScaleChangefeedCase)

	awsMySQLChangefeedSmokeCase := changefeed.NewMySQLChangefeedSmokeCase(AWS)
	gcpMySQLChangefeedSmokeCase := changefeed.NewMySQLChangefeedSmokeCase(GCP)
	azureMySQLChangefeedSmokeCase := changefeed.NewMySQLChangefeedSmokeCase(AZURE)
	alicloudMySQLChangefeedSmokeCase := changefeed.NewMySQLChangefeedSmokeCase(AliCloud)
	addCases(awsMySQLChangefeedSmokeCase, gcpMySQLChangefeedSmokeCase, azureMySQLChangefeedSmokeCase, alicloudMySQLChangefeedSmokeCase)

	awsS3ChangefeedSmokeCase := changefeed.NewS3ChangefeedSmokeCase(AWS)
	addCases(awsS3ChangefeedSmokeCase)

	awsPulsarChangefeedSmokeCase := changefeed.NewPulsarChangefeedSmokeCase(AWS)
	gcpPulsarChangefeedSmokeCase := changefeed.NewPulsarChangefeedSmokeCase(GCP)
	azurePulsarChangefeedSmokeCase := changefeed.NewPulsarChangefeedSmokeCase(AZURE)
	alicloudPulsarChangefeedSmokeCase := changefeed.NewPulsarChangefeedSmokeCase(AliCloud)
	addCases(awsPulsarChangefeedSmokeCase, gcpPulsarChangefeedSmokeCase, azurePulsarChangefeedSmokeCase, alicloudPulsarChangefeedSmokeCase)

	awsValidateAllMachineTypeCase := changefeed.NewValidateAllMachineTypeCase(AWS)
	gcpValidateAllMachineTypeCase := changefeed.NewValidateAllMachineTypeCase(GCP)
	azureValidateAllMachineTypeCase := changefeed.NewValidateAllMachineTypeCase(AZURE)
	alicloudValidateAllMachineTypeCase := changefeed.NewValidateAllMachineTypeCase(AliCloud)
	addCases(awsValidateAllMachineTypeCase, gcpValidateAllMachineTypeCase, azureValidateAllMachineTypeCase, alicloudValidateAllMachineTypeCase)

	awsCdcRecreateCase := changefeed.NewCdcRecreateCase(AWS)
	gcpCdcRecreateCase := changefeed.NewCdcRecreateCase(GCP)
	azureCdcRecreateCase := changefeed.NewCdcRecreateCase(AZURE)
	alicloudCdcRecreateCase := changefeed.NewCdcRecreateCase(AliCloud)
	addCases(awsCdcRecreateCase, gcpCdcRecreateCase, azureCdcRecreateCase, alicloudCdcRecreateCase)

	awsChangefeedConfigOperationsCase := changefeed.NewChangefeedConfigOperationsCase(AWS)
	gcpChangefeedConfigOperationsCase := changefeed.NewChangefeedConfigOperationsCase(GCP)
	azureChangefeedConfigOperationsCase := changefeed.NewChangefeedConfigOperationsCase(AZURE)
	alicloudChangefeedConfigOperationsCase := changefeed.NewChangefeedConfigOperationsCase(AliCloud)
	addCases(awsChangefeedConfigOperationsCase, gcpChangefeedConfigOperationsCase, azureChangefeedConfigOperationsCase, alicloudChangefeedConfigOperationsCase)

	awsTiCDCClusterConfigOperationsCase := changefeed.NewTiCDCClusterConfigOperationsCase(AWS)
	gcpTiCDCClusterConfigOperationsCase := changefeed.NewTiCDCClusterConfigOperationsCase(GCP)
	azureTiCDCClusterConfigOperationsCase := changefeed.NewTiCDCClusterConfigOperationsCase(AZURE)
	alicloudTiCDCClusterConfigOperationsCase := changefeed.NewTiCDCClusterConfigOperationsCase(AliCloud)
	addCases(awsTiCDCClusterConfigOperationsCase, gcpTiCDCClusterConfigOperationsCase, azureTiCDCClusterConfigOperationsCase, alicloudTiCDCClusterConfigOperationsCase)

	// Premium DM cases
	awsDMFullMigrationSmokeCase := dm.NewDMFullMigrationSmokeCase(AWS)
	gcpDMFullMigrationSmokeCase := dm.NewDMFullMigrationSmokeCase(GCP)
	azureDMFullMigrationSmokeCase := dm.NewDMFullMigrationSmokeCase(AZURE)
	alicloudDMFullMigrationSmokeCase := dm.NewDMFullMigrationSmokeCase(AliCloud)
	addCases(awsDMFullMigrationSmokeCase, gcpDMFullMigrationSmokeCase, azureDMFullMigrationSmokeCase, alicloudDMFullMigrationSmokeCase)

	awsDMIncrementalMigrationSmokeCase := dm.NewDMIncrementalMigrationSmokeCase(AWS)
	gcpDMIncrementalMigrationSmokeCase := dm.NewDMIncrementalMigrationSmokeCase(GCP)
	azureDMIncrementalMigrationSmokeCase := dm.NewDMIncrementalMigrationSmokeCase(AZURE)
	alicloudDMIncrementalMigrationSmokeCase := dm.NewDMIncrementalMigrationSmokeCase(AliCloud)
	addCases(awsDMIncrementalMigrationSmokeCase, gcpDMIncrementalMigrationSmokeCase, azureDMIncrementalMigrationSmokeCase, alicloudDMIncrementalMigrationSmokeCase)

	awsDMMigrationLifecycleSmokeCase := dm.NewDMMigrationLifecycleSmokeCase(AWS)
	gcpDMMigrationLifecycleSmokeCase := dm.NewDMMigrationLifecycleSmokeCase(GCP)
	azureDMMigrationLifecycleSmokeCase := dm.NewDMMigrationLifecycleSmokeCase(AZURE)
	alicloudDMMigrationLifecycleSmokeCase := dm.NewDMMigrationLifecycleSmokeCase(AliCloud)
	addCases(awsDMMigrationLifecycleSmokeCase, gcpDMMigrationLifecycleSmokeCase, azureDMMigrationLifecycleSmokeCase, alicloudDMMigrationLifecycleSmokeCase)

	awsDMPrecheckSmokeCase := dm.NewDMPrecheckSmokeCase(AWS)
	gcpDMPrecheckSmokeCase := dm.NewDMPrecheckSmokeCase(GCP)
	azureDMPrecheckSmokeCase := dm.NewDMPrecheckSmokeCase(AZURE)
	alicloudDMPrecheckSmokeCase := dm.NewDMPrecheckSmokeCase(AliCloud)
	addCases(awsDMPrecheckSmokeCase, gcpDMPrecheckSmokeCase, azureDMPrecheckSmokeCase, alicloudDMPrecheckSmokeCase)

	awsPremiumImportSmokeCase := import_data.NewImportSmokeCase(AWS)
	alicloudPremiumImportSmokeCase := import_data.NewImportSmokeCase(AliCloud)
	addCases(awsPremiumImportSmokeCase, alicloudPremiumImportSmokeCase)

	// Import data-format cases (AURORA_SNAPSHOT/PARQUET). These run only when
	// selected by name or through the automatic "all" group; they are
	// intentionally not part of the smoke/weekly groups.
	awsImportAuroraSnapshotSmokeCase := import_data.NewImportDataFormatSmokeCase(AWS, config.DataFormatAuroraSnapshot)
	awsImportParquetSmokeCase := import_data.NewImportDataFormatSmokeCase(AWS, config.DataFormatParquet)
	addCases(awsImportAuroraSnapshotSmokeCase, awsImportParquetSmokeCase)

	printAllCasesName()

	// group cases
	CaseGroups = map[string][]cases.E2ECase{
		// will be assembled automatically
		"all":              {},
		"awsAll":           {},
		"gcpAll":           {},
		"azureAll":         {},
		"alicloudAll":      {},
		"smoke":            {},
		"weeklyRegression": {},

		// manual group
		"awsSmoke": {
			awsKafkaChangefeedSmokeCase,
			awsMySQLChangefeedSmokeCase,
			awsDMPrecheckSmokeCase,
			awsPremiumImportSmokeCase,
		},
		"gcpSmoke": {
			gcpKafkaChangefeedSmokeCase,
			gcpMySQLChangefeedSmokeCase,
			gcpDMPrecheckSmokeCase,
		},
		"azureSmoke": {
			azureKafkaChangefeedSmokeCase,
			azureMySQLChangefeedSmokeCase,
			azureDMPrecheckSmokeCase,
		},
		"alicloudSmoke": {
			alicloudKafkaChangefeedSmokeCase,
			alicloudMySQLChangefeedSmokeCase,
			alicloudDMPrecheckSmokeCase,
			alicloudPremiumImportSmokeCase,
		},
		"awsWeeklyRegression": {
			awsKafkaChangefeedSmokeCase,
			awsMySQLChangefeedSmokeCase,
			awsKafkaPrivateLink,
			awsChangefeedConfigOperationsCase,
			awsDMFullMigrationSmokeCase,
			awsDMIncrementalMigrationSmokeCase,
			awsDMMigrationLifecycleSmokeCase,
			awsDMPrecheckSmokeCase,
			awsPremiumImportSmokeCase,
		},
		"gcpWeeklyRegression": {
			gcpKafkaChangefeedSmokeCase,
			gcpMySQLChangefeedSmokeCase,
			gcpPulsarChangefeedSmokeCase,
			gcpKafkaPrivateLink,
			gcpDMFullMigrationSmokeCase,
			gcpDMIncrementalMigrationSmokeCase,
			gcpDMMigrationLifecycleSmokeCase,
			gcpDMPrecheckSmokeCase,
		},
		"azureWeeklyRegression": {
			azureKafkaChangefeedSmokeCase,
			azureMySQLChangefeedSmokeCase,
			azurePulsarChangefeedSmokeCase,
			azureKafkaPrivateLink,
			azureDMFullMigrationSmokeCase,
			azureDMIncrementalMigrationSmokeCase,
			azureDMMigrationLifecycleSmokeCase,
			azureDMPrecheckSmokeCase,
		},
		"alicloudWeeklyRegression": {
			alicloudKafkaChangefeedSmokeCase,
			alicloudMySQLChangefeedSmokeCase,
			alicloudKafkaPrivateLink,
			alicloudChangefeedConfigOperationsCase,
			alicloudDMFullMigrationSmokeCase,
			alicloudDMIncrementalMigrationSmokeCase,
			alicloudDMMigrationLifecycleSmokeCase,
			alicloudDMPrecheckSmokeCase,
			alicloudPremiumImportSmokeCase,
		},
		"awsNewRegion": {
			// CDC
			awsKafkaChangefeedSmokeCase,
			awsKafkaKernelConfiguration,
			awsTestConnection,
			awsKafkaValidateChangefeedParams,
			awsMySQLChangefeedSmokeCase,
			awsPulsarChangefeedSmokeCase,
			awsScaleChangefeedCase,
			awsValidateAllMachineTypeCase,
			awsCdcRecreateCase,
			awsChangefeedConfigOperationsCase,
			awsTiCDCClusterConfigOperationsCase,
			// DM
			awsDMFullMigrationSmokeCase,
			awsDMIncrementalMigrationSmokeCase,
			awsDMMigrationLifecycleSmokeCase,
			awsDMPrecheckSmokeCase,
			// Import
			awsPremiumImportSmokeCase,
		},
		"gcpNewRegion": {
			// CDC
			gcpKafkaChangefeedSmokeCase,
			gcpKafkaKernelConfiguration,
			gcpTestConnection,
			gcpKafkaValidateChangefeedParams,
			gcpMySQLChangefeedSmokeCase,
			gcpPulsarChangefeedSmokeCase,
			gcpScaleChangefeedCase,
			gcpValidateAllMachineTypeCase,
			gcpCdcRecreateCase,
			gcpChangefeedConfigOperationsCase,
			gcpTiCDCClusterConfigOperationsCase,
			// DM
			gcpDMFullMigrationSmokeCase,
			gcpDMIncrementalMigrationSmokeCase,
			gcpDMMigrationLifecycleSmokeCase,
			gcpDMPrecheckSmokeCase,
		},
		"azureNewRegion": {
			// CDC
			azureKafkaChangefeedSmokeCase,
			azureKafkaAvroChangefeedCase,
			azureKafkaKernelConfiguration,
			azureTestConnection,
			azureKafkaValidateChangefeedParams,
			azureMySQLChangefeedSmokeCase,
			azurePulsarChangefeedSmokeCase,
			azureScaleChangefeedCase,
			azureValidateAllMachineTypeCase,
			azureCdcRecreateCase,
			azureChangefeedConfigOperationsCase,
			azureTiCDCClusterConfigOperationsCase,
			// DM
			azureDMFullMigrationSmokeCase,
			azureDMIncrementalMigrationSmokeCase,
			azureDMMigrationLifecycleSmokeCase,
			azureDMPrecheckSmokeCase,
		},
		"alicloudNewRegion": {
			// CDC
			alicloudKafkaChangefeedSmokeCase,
			alicloudKafkaKernelConfiguration,
			alicloudTestConnection,
			alicloudKafkaValidateChangefeedParams,
			alicloudMySQLChangefeedSmokeCase,
			alicloudPulsarChangefeedSmokeCase,
			alicloudScaleChangefeedCase,
			alicloudValidateAllMachineTypeCase,
			alicloudCdcRecreateCase,
			alicloudChangefeedConfigOperationsCase,
			alicloudTiCDCClusterConfigOperationsCase,
			// DM
			alicloudDMFullMigrationSmokeCase,
			alicloudDMIncrementalMigrationSmokeCase,
			alicloudDMMigrationLifecycleSmokeCase,
			alicloudDMPrecheckSmokeCase,
			// Import
			alicloudPremiumImportSmokeCase,
		},
	}

	// auto group
	for _, v := range AllCases {
		CaseGroups["all"] = append(CaseGroups["all"], v)
		reqs := pie.Filter(pie.Values(v.DeclareDependencyRequirements()), func(it DependencyRequirement) bool {
			return it.Type() == TiDBPremium
		})

		if pie.All(reqs, func(value DependencyRequirement) bool { return value.(*TiDBPremiumRequirement).CloudProvider == AWS }) {
			CaseGroups["awsAll"] = append(CaseGroups["awsAll"], v)
		}
		if pie.All(reqs, func(value DependencyRequirement) bool { return value.(*TiDBPremiumRequirement).CloudProvider == GCP }) {
			CaseGroups["gcpAll"] = append(CaseGroups["gcpAll"], v)
		}
		if pie.All(reqs, func(value DependencyRequirement) bool {
			return value.(*TiDBPremiumRequirement).CloudProvider == AZURE
		}) {
			CaseGroups["azureAll"] = append(CaseGroups["azureAll"], v)
		}
		if pie.All(reqs, func(value DependencyRequirement) bool {
			return value.(*TiDBPremiumRequirement).CloudProvider == AliCloud
		}) {
			CaseGroups["alicloudAll"] = append(CaseGroups["alicloudAll"], v)
		}
	}
	CaseGroups["smoke"] = append(CaseGroups["smoke"], CaseGroups["awsSmoke"]...)
	CaseGroups["smoke"] = append(CaseGroups["smoke"], CaseGroups["alicloudSmoke"]...)
	CaseGroups["weeklyRegression"] = append(CaseGroups["weeklyRegression"], CaseGroups["awsWeeklyRegression"]...)
	CaseGroups["weeklyRegression"] = append(CaseGroups["weeklyRegression"], CaseGroups["alicloudWeeklyRegression"]...)

	printCaseGroups()

	// filter cases by domain
	filterCasesByDomain()
}
