package internal

import (
	"os"

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

	"github.com/tidbcloud/auto-deploy/internal/argocd"
	cloud_provider "github.com/tidbcloud/auto-deploy/internal/cloud-provider"
	"github.com/tidbcloud/auto-deploy/internal/constants"
	global_client "github.com/tidbcloud/auto-deploy/internal/global-client"
	"github.com/tidbcloud/auto-deploy/internal/job"
	"github.com/tidbcloud/auto-deploy/internal/meta"
	oidc_provider "github.com/tidbcloud/auto-deploy/internal/oidc-provider"
	"github.com/tidbcloud/auto-deploy/internal/types"
)

type DestroyAzureRegionK8sArgs struct {
	OidcProviderType types.OidcProviderType
	InstanceName     string
	RegionName       string
	Region           string
	MetaURI          string
	TenantId         string
	SubscriptionId   string
	ClientId         string
}

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

	account, err := types.FromAzureClientId(args.TenantId, args.SubscriptionId, args.ClientId)
	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")
	cloudProvider, err := cloud_provider.NewAzureCloudProvider(oidcProvider, *account, args.Region)
	if err != nil {
		return err
	}
	logger.WithField("account", account.AzureClientId).Debug("Auth to Azure")

	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 temp credential files to host")

	logger.Debug("Start to destory azure region")
	region, err := meta.LoadAzureRegionControl(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.Azure {
		return errors.BadRequestf("Region cloud provider is not %s", types.Azure)
	}

	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.AZURE_SECRET_NAME
	region.K8s.CredentialSecret = cloudProvider.GetAuthConfigYaml(constants.AZURE_SECRET_NAME, region.TidbClusterAccounts)

	err = CheckRegionResource(region)
	if err != nil {
		return err
	}

	err = job.RunFinalizerJobs(region)
	if err != nil {
		return err
	}

	err = argocd.UnregisterK8s(&region.K8s)
	if err != nil {
		return err
	}

	err = cloudProvider.DestroyK8s(&region.K8s)
	if err != nil {
		logger.WithField("error", err).Error("Failed to destroy azure region k8s")
		return err
	}

	region.JobOutputs = make(map[string]types.JobOutput)
	logger.Info("Finished to destroy azure region k8s")
	err = meta.SaveAzureRegionControl(args.MetaURI, *region)
	if err != nil {
		region.Print()
	}

	authKey := os.Getenv(constants.GLOBAL_AUTH_KEY_ENV)
	client := global_client.NewGlobalClient(region.GlobalOptions.Env, authKey, global_client.DEFAULT_TIMEOUT, log.IsLevelEnabled(log.DebugLevel))
	return client.DeleteRegionById(global_client.DEPLOY_TYPE_DEDICATED, region.GlobalOptions.LogicalRegionName, region.CloudProviderType)
}
