package internal

import (
	"os"
	"time"

	"github.com/juju/errors"
	log "github.com/sirupsen/logrus"

	cloud_provider "github.com/tidbcloud/auto-deploy/internal/cloud-provider"
	"github.com/tidbcloud/auto-deploy/internal/constants"
	"github.com/tidbcloud/auto-deploy/internal/meta"
	"github.com/tidbcloud/auto-deploy/internal/metrics"
	oidc_provider "github.com/tidbcloud/auto-deploy/internal/oidc-provider"
	"github.com/tidbcloud/auto-deploy/internal/types"
)

type RecreateAwsRegionK8sArgs struct {
	OidcProviderType types.OidcProviderType
	InstanceName     string
	RegionName       string
	Region           string
	MetaURI          string
	RoleArn          string
}

func RereateAwsRegionK8s(args RecreateAwsRegionK8sArgs) error {
	logger := log.WithFields(log.Fields{
		"instance": args.InstanceName,
		"name":     args.RegionName,
		"meta-uri": args.MetaURI,
	})

	logger.Debug("Start to create aws region k8s")
	metrics.AddCommonLabel(metrics.LABEL_CLOUD_PROVIDER, "aws")
	metrics.AddCommonLabel(metrics.LABEL_CLOUD_REGION, args.Region)
	metrics.AddCommonLabel(metrics.LABEL_REGION_NAME, args.RegionName)
	metrics.AddCommonLabel(metrics.LABEL_ENVIRONMENT, args.InstanceName)
	metrics.AddCommonLabel(metrics.LABEL_DEPLOY_TYPE, "dedicated-region")
	metrics.AddCommonLabel(metrics.LABEL_DEPOLY_METHOD, "re-deploy")

	account, err := types.FromAwsArn(args.RoleArn)
	if err != nil {
		return err
	}
	oidcProvider, err := oidc_provider.GetProvider(args.OidcProviderType)
	if err != nil {
		return err
	}
	logger.WithField("oidc-provider", args.OidcProviderType).Debug("Get load oidc provider")
	metrics.AddCommonLabel(metrics.LABEL_DEPLOY_ID, oidcProvider.GetRunID())

	cloudProvider, err := cloud_provider.NewAWSCloudProvider(oidcProvider, *account, args.Region)
	if err != nil {
		return err
	}
	logger.WithField("account", account.AwsRole.AccountId).Debug("Auth to AWS")

	homeDir, err := os.UserHomeDir()
	if err != nil {
		return errors.Annotatef(err, "Failed to get home dir")
	}
	cloudProvider.WriteToLocal(homeDir, []types.Account{})
	logger.WithField("home-dir", homeDir).Info("Write credential files to host")

	region, err := meta.LoadRegionControl(args.MetaURI, args.InstanceName, args.RegionName)
	if err != nil {
		return err
	}
	logger.Debug("Loaded region meta")

	if region.Region != args.Region {
		return errors.BadRequestf("Region not match with meta %s != %s", region.Region, args.Region)
	}

	if region.CloudProviderType != types.AWS {
		return errors.BadRequestf("Region cloud provider is not %s", types.AWS)
	}

	cloudProvider.WriteToLocal(homeDir, region.TidbClusterAccounts)
	logger.WithField("home-dir", homeDir).Info("Write credential files to host")

	region.CloudProvider = cloudProvider
	region.OidcProvider = oidcProvider
	region.LatestRunId = oidcProvider.GetRunID()
	region.K8s.CredentialSecretName = constants.AWS_SECRET_NAME
	region.K8s.CredentialSecret = cloudProvider.GetAuthConfigYaml(region.K8s.CredentialSecretName, region.TidbClusterAccounts)
	startedAt := time.Now()
	err = cloudProvider.CreateK8s(&region.K8s)
	if err == nil {
		logger.Info("Finished to recreate aws region k8s")
		// recreaed k8s, cleaer job output
		region.JobOutputs = make(map[string]types.JobOutput)
		metrics.AddMetric(metrics.METRIC_CREATE_K8S_DURATION, time.Since(startedAt).Seconds())
	} else if !errors.Is(err, errors.AlreadyExists) {
		logger.Error("Failed to recreate aws region k8s")
		return err
	}

	err = deployRegion(region, false)

	err2 := meta.SaveRegionControl(args.MetaURI, *region)
	if err2 != nil {
		logger.Error("Failed to save region meta")
		region.Print()
	} else {
		logger.Info("Saved region meta")
	}
	return err
}
