package import_data

import (
	"fmt"
	"strings"
	"time"

	"github.com/tidbcloud/dataflow-service-e2e/internal/config"
	. "github.com/tidbcloud/dataflow-service-e2e/internal/model"
	import_model "github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/premium/consoleapi/import/model"
)

const (
	DefaultImportTimeout = 30 * time.Minute

	DefaultRetryAttempts = 3
	DefaultRetryInterval = time.Minute

	ImportedDatabase = "bikeshare"
	ImportedTable    = "trips"
)

func GenerateImportName(prefix string) string {
	return fmt.Sprintf("e2e-%s-%d", prefix, time.Now().Unix())
}

func BuildImportIntoTask(name string, cluster *TiDBPremiumEntity) (*import_model.V1beta2ImportIntoTask, error) {
	return BuildImportIntoTaskWithSampleData(name, cluster, config.GlobalConfig.ImportSampleData)
}

// BuildImportIntoTaskWithItem builds a premium import task for a configured
// importData item (S3 source with an explicit data format; the backend
// auto-detects the file type from the source files).
func BuildImportIntoTaskWithItem(name string, cluster *TiDBPremiumEntity, item config.ImportDataItem) (*import_model.V1beta2ImportIntoTask, error) {
	if strings.TrimSpace(item.SourceURL) == "" || strings.TrimSpace(item.RoleARN) == "" {
		return nil, fmt.Errorf("premium import data item %s is missing sourceURL or roleARN", item.DataFormat)
	}
	sourceType := import_model.V1beta2ImportSourceTypeEnumENUMS3
	authType := import_model.V1beta2ImportS3AuthTypeEnumENUMROLEARN
	return &import_model.V1beta2ImportIntoTask{
		Name:     name,
		Username: cluster.User,
		Password: cluster.Password,
		CreationDetails: &import_model.V1beta2CreationDetails{
			Source: &import_model.V1beta2ImportSource{
				Type: &sourceType,
				S3: &import_model.V1beta2S3Source{
					URI:      item.SourceURL,
					AuthType: &authType,
					RoleArn:  item.RoleARN,
				},
			},
		},
	}, nil
}

func BuildImportIntoTaskWithSampleData(
	name string,
	cluster *TiDBPremiumEntity,
	sampleData config.ImportSampleDataConfig,
) (*import_model.V1beta2ImportIntoTask, error) {
	source, err := buildImportSource(cluster.CloudProvider, sampleData)
	if err != nil {
		return nil, err
	}

	return &import_model.V1beta2ImportIntoTask{
		Name:     name,
		Username: cluster.User,
		Password: cluster.Password,
		CreationDetails: &import_model.V1beta2CreationDetails{
			Source:        source,
			ImportOptions: buildImportOptions(cluster.CloudProvider, sampleData),
		},
	}, nil
}

func buildImportSource(
	provider CloudProviderType,
	sampleData config.ImportSampleDataConfig,
) (*import_model.V1beta2ImportSource, error) {
	switch provider {
	case AWS:
		sourceType := import_model.V1beta2ImportSourceTypeEnumENUMS3
		authType := import_model.V1beta2ImportS3AuthTypeEnumENUMROLEARN
		return &import_model.V1beta2ImportSource{
			Type: &sourceType,
			S3: &import_model.V1beta2S3Source{
				URI:      sampleData.S3.SourceURL,
				AuthType: &authType,
				RoleArn:  sampleData.S3.RoleARN,
			},
		}, nil
	case AliCloud:
		sourceType := import_model.V1beta2ImportSourceTypeEnumENUMOSS
		authType := import_model.V1beta2ImportOSSAuthTypeEnumENUMACCESSKEY
		return &import_model.V1beta2ImportSource{
			Type: &sourceType,
			Oss: &import_model.V1beta2OSSSource{
				URI:      sampleData.OSS.SourceURL,
				Endpoint: sampleData.OSS.Endpoint,
				AuthType: &authType,
				AccessKey: &import_model.V1beta2OSSSourceAccessKey{
					ID:     sampleData.OSS.AccessKeyID,
					Secret: sampleData.OSS.AccessKeySecret,
				},
			},
		}, nil
	default:
		return nil, fmt.Errorf("unsupported premium import source mapping for provider %s", provider)
	}
}

func buildImportOptions(provider CloudProviderType, sampleData config.ImportSampleDataConfig) *import_model.V1beta2ImportOptions {
	if provider != AliCloud || sampleData.OSS.CustomCSVFormat == nil {
		return nil
	}

	customCSVFormat := sampleData.OSS.CustomCSVFormat
	return &import_model.V1beta2ImportOptions{
		CsvFormat: &import_model.V1beta2CSVFormat{
			Separator:      customCSVFormat.Separator,
			Delimiter:      customCSVFormat.Delimiter,
			LineTerminator: customCSVFormat.LineTerminator,
			EscapeChar:     customCSVFormat.EscapeChar,
			SkipRows:       customCSVFormat.SkipRows,
			NullValue:      customCSVFormat.NullValue,
			SplitFile:      customCSVFormat.SplitFile,
		},
	}
}

func resolveImportedDatabaseAndTable(
	provider CloudProviderType,
	sampleData config.ImportSampleDataConfig,
) (string, string) {
	importedDatabase := ImportedDatabase
	importedTable := ImportedTable

	if provider != AliCloud {
		return importedDatabase, importedTable
	}

	if sampleData.OSS.ImportedDBTable != nil {
		if sampleData.OSS.ImportedDBTable.Database != "" {
			importedDatabase = sampleData.OSS.ImportedDBTable.Database
		}
		if sampleData.OSS.ImportedDBTable.Table != "" {
			importedTable = sampleData.OSS.ImportedDBTable.Table
		}
	}

	return importedDatabase, importedTable
}
