package namer

import (
	"strings"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"sigs.k8s.io/controller-runtime/pkg/client"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/consts"
)

const (
	nodeLabelEKSNodeGroup      = "eks.amazonaws.com/nodegroup"
	nodeLabelEKSNodeGroupExtra = "Name"
	nodeLabelGKENodePool       = "cloud.google.com/gke-nodepool"
	nodeLabelAKSAgentPool      = "kubernetes.azure.com/agentpool"
)

func GetNodeGroupNameFromNode(labels map[string]string, provider string, isExtra bool) string {
	if labels == nil {
		return ""
	}
	switch provider {
	case cloudv1.ProviderTypeEKS:
		// EKS uses eks.amazonaws.com/nodegroup label
		if isExtra {
			if ngName, ok := labels[nodeLabelEKSNodeGroupExtra]; ok {
				return ngName
			}
		}
		if ngName, ok := labels[nodeLabelEKSNodeGroup]; ok {
			return ngName
		}
	case cloudv1.ProviderTypeGKE:
		// GKE uses cloud.google.com/gke-nodepool label
		if ngName, ok := labels[nodeLabelGKENodePool]; ok {
			return ngName
		}
	case cloudv1.ProviderTypeAKS:
		// AKS uses kubernetes.azure.com/agentpool label
		if ngName, ok := labels[nodeLabelAKSAgentPool]; ok {
			return ngName
		}
	}

	return ""
}

func GetNodeZoneFromLabels(labels map[string]string) string {
	if labels == nil {
		return ""
	}
	return labels[consts.ZoneLabelKey]
}

func GetNodeInstanceTypeFromLabels(labels map[string]string) string {
	if labels == nil {
		return ""
	}
	return labels[corev1.LabelInstanceTypeStable]
}

func GVKString(gvk *schema.GroupVersionKind) string {
	if len(gvk.Group) > 0 {
		return gvk.Group + "." + gvk.Version + "." + strings.ToLower(gvk.Kind)
	}

	return gvk.Version + "." + strings.ToLower(gvk.Kind)
}

func NewOwnerLabels(owner client.Object, labels map[string]string) map[string]string {
	gvk := owner.GetObjectKind().GroupVersionKind()
	namespace := owner.GetNamespace()
	name := owner.GetName()
	uid := string(owner.GetUID())

	if labels == nil {
		labels = map[string]string{}
	}

	labels[consts.LabelKeyOwnedBy] = GVKString(&gvk)
	labels[consts.LabelKeyNamespace] = namespace
	labels[consts.LabelKeyName] = name
	labels[consts.LabelKeyUID] = uid

	return labels
}
