package cvt

import (
	"fmt"

	"github.com/pingcap/log"
	"github.com/tidbcloud/core-svc/idl/pbgen/proto/core"
	entity "github.com/tidbcloud/core-svc/model"
	"github.com/tidbcloud/idl/pbgen/proto/openapi/cm"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/pkgv2/bizerr"
	"go.uber.org/zap"
)

func CloudProviderCore2OpenAPI(cloudProvider string) cm.CloudProvider {
	switch cloudProvider {
	case entity.Aws.String():
		return cm.CloudProvider_AWS
	case entity.Gcp.String():
		return cm.CloudProvider_GCP
	}
	panic(fmt.Sprintf("unsupported cloud provider: %s", cloudProvider))
}

func ClusterStatusCore2OpenAPI(cluster *core.Cluster) cm.ClusterStatus {
	switch cluster.UserStatus {
	case core.UserClusterStatus_USER_CLUSTER_STATUS_NORMAL:
		return cm.ClusterStatus_AVAILABLE
	case core.UserClusterStatus_USER_CLUSTER_STATUS_CREATING:
		return cm.ClusterStatus_CREATING
	case core.UserClusterStatus_USER_CLUSTER_STATUS_PAUSED:
		return cm.ClusterStatus_PAUSED
	case core.UserClusterStatus_USER_CLUSTER_STATUS_RESUMING:
		return cm.ClusterStatus_RESUMING
	case core.UserClusterStatus_USER_CLUSTER_STATUS_IMPORTING:
		return cm.ClusterStatus_IMPORTING
	case core.UserClusterStatus_USER_CLUSTER_STATUS_UNAVAILABLE:
		return cm.ClusterStatus_UNAVAILABLE
	default:
		return cm.ClusterStatus_MODIFYING
	}
}

func ConvertNodeStatus(s cloudv1.MemberStatus) cm.NodeStatus {
	switch s {
	case cloudv1.MemberStatusNormal:
		return cm.NodeStatus_NODE_STATUS_AVAILABLE
	case cloudv1.MemberStatusCreating:
		return cm.NodeStatus_NODE_STATUS_CREATING
	case cloudv1.MemberStatusUnavailable:
		return cm.NodeStatus_NODE_STATUS_UNAVAILABLE
	case cloudv1.MemberStatusTerminating, cloudv1.MemberStatusLeaving:
		return cm.NodeStatus_NODE_STATUS_DELETING
	default:
		log.Error("unknown tc member status", zap.String("status", string(s)))
		return cm.NodeStatus_NODE_STATUS_AVAILABLE
	}
}

func CloudProviderOpenAPI2Core(cloudProvider cm.CloudProvider) (string, bizerr.BizError) {
	switch cloudProvider {
	case cm.CloudProvider_AWS:
		return entity.Aws.String(), nil
	case cm.CloudProvider_GCP:
		return entity.Gcp.String(), nil
	}
	return "", bizerr.New(bizerr.ErrCodeParams, "cloud provider unspecified")
}

func DeployTypeOpenAPI2Core(clusterType cm.ClusterType) (core.DeployType, bizerr.BizError) {
	switch clusterType {
	case cm.ClusterType_DEDICATED:
		return core.DeployType_DEPLOY_TYPE_DEDICATED, nil
	case cm.ClusterType_DEVELOPER:
		return core.DeployType_DEPLOY_TYPE_SHARED, nil
	}
	return core.DeployType_DEPLOY_TYPE_UNSPECIFIED, bizerr.New(bizerr.ErrCodeParams, "deploy type unspecified")
}

func DeployTypeCore2OpenAPI(deployType core.DeployType) cm.ClusterType {
	switch deployType {
	case core.DeployType_DEPLOY_TYPE_DEDICATED:
		return cm.ClusterType_DEDICATED
	case core.DeployType_DEPLOY_TYPE_SHARED:
		return cm.ClusterType_DEVELOPER
	}
	panic(fmt.Sprintf("unsupported deploy type: %s", deployType))
}
