package k8sresource

import (
	"strings"

	"k8s.io/apimachinery/pkg/runtime/schema"
)

type builtinGV struct {
	group   string
	version string
}

// coreKindsV1 are API group "" resources (v1).
var coreKindsV1 = map[string]struct{}{
	"Pod":                   {},
	"Service":               {},
	"ConfigMap":             {},
	"Secret":                {},
	"Namespace":             {},
	"PersistentVolumeClaim": {},
	"PersistentVolume":      {},
	"Node":                  {},
	"Event":                 {},
	"Endpoints":             {},
	"ServiceAccount":        {},
	"ReplicationController": {},
	"ResourceQuota":         {},
	"LimitRange":            {},
}

// wellKnownBuiltin maps Kind to fixed group/version for common built-in APIs (non-core group).
var wellKnownBuiltin = map[string]builtinGV{
	"Deployment":              {group: "apps", version: "v1"},
	"StatefulSet":             {group: "apps", version: "v1"},
	"DaemonSet":               {group: "apps", version: "v1"},
	"ReplicaSet":              {group: "apps", version: "v1"},
	"ControllerRevision":      {group: "apps", version: "v1"},
	"Job":                     {group: "batch", version: "v1"},
	"CronJob":                 {group: "batch", version: "v1"},
	"Ingress":                 {group: "networking.k8s.io", version: "v1"},
	"NetworkPolicy":           {group: "networking.k8s.io", version: "v1"},
	"IngressClass":            {group: "networking.k8s.io", version: "v1"},
	"StorageClass":            {group: "storage.k8s.io", version: "v1"},
	"CSIDriver":               {group: "storage.k8s.io", version: "v1"},
	"CSINode":                 {group: "storage.k8s.io", version: "v1"},
	"VolumeAttachment":        {group: "storage.k8s.io", version: "v1"},
	"PriorityClass":           {group: "scheduling.k8s.io", version: "v1"},
	"RuntimeClass":            {group: "node.k8s.io", version: "v1"},
	"HorizontalPodAutoscaler": {group: "autoscaling", version: "v2"},
}

var (
	builtinByCanonicalKind map[string]builtinGV
	builtinByLowerKind     map[string]string
)

func init() {
	builtinByCanonicalKind = make(map[string]builtinGV, len(coreKindsV1)+len(wellKnownBuiltin))
	builtinByLowerKind = make(map[string]string, len(coreKindsV1)+len(wellKnownBuiltin))

	for kind := range coreKindsV1 {
		builtinByCanonicalKind[kind] = builtinGV{group: "", version: "v1"}
		registerBuiltinKindIndex(kind)
	}
	for kind, gv := range wellKnownBuiltin {
		builtinByCanonicalKind[kind] = gv
		registerBuiltinKindIndex(kind)
	}
}

func registerBuiltinKindIndex(canonical string) {
	builtinByLowerKind[strings.ToLower(canonical)] = canonical
}

// lookupBuiltin matches kind against CoreKind and WellKnownBuiltin tables (case-insensitive).
func lookupBuiltin(kind string) (canonical string, gv builtinGV, ok bool) {
	trimmed := strings.TrimSpace(kind)
	if trimmed == "" {
		return "", builtinGV{}, false
	}
	if c, hit := builtinByLowerKind[strings.ToLower(trimmed)]; hit {
		return c, builtinByCanonicalKind[c], true
	}
	return trimmed, builtinGV{}, false
}

func gvkFieldsEmpty(group, version string) bool {
	return group == "" && version == ""
}

func gvkCompatible(userGroup, userVersion string, table builtinGV) bool {
	if userGroup != "" && userGroup != table.group {
		return false
	}
	if userVersion != "" && userVersion != table.version {
		return false
	}
	return true
}

func mergeBuiltinGVK(canonicalKind, userGroup, userVersion string, table builtinGV) schema.GroupVersionKind {
	group := table.group
	if userGroup != "" {
		group = userGroup
	}
	version := table.version
	if userVersion != "" {
		version = userVersion
	}
	return schema.GroupVersionKind{Group: group, Version: version, Kind: canonicalKind}
}
