package util

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

// GetAnnotation gets the annotation value for the given key.
// If the annotation is not set, it returns an empty string.
func GetAnnotation(obj client.Object, key string) string {
	annotations := obj.GetAnnotations()
	if annotations == nil {
		return ""
	}
	return annotations[key]
}

// GetAnnotationWithDefault gets the annotation value for the given key.
// If the annotation is not set or is empty, it returns the provided default value.
func GetAnnotationWithDefault(obj client.Object, key, defVal string) string {
	if v := GetAnnotation(obj, key); v != "" {
		return v
	}
	return defVal
}

// SetAnnotation sets the annotation for the given key to the provided value.
// If the annotations map is nil, it initializes it.
func SetAnnotation(obj client.Object, key, value string) {
	annotations := obj.GetAnnotations()
	if annotations == nil {
		annotations = make(map[string]string)
	}
	annotations[key] = value
	obj.SetAnnotations(annotations)
}

// SetAnnotationIfEmpty sets the annotation for the given key to the provided default value
// if the annotation is not already set or is empty, it returns the final value of the annotation.
func SetAnnotationIfEmpty(obj client.Object, key, defVal string) string {
	v := GetAnnotation(obj, key)
	if v == "" {
		v = defVal
		SetAnnotation(obj, key, v)
	}
	return v
}

// GetLabel gets the label value for the given key.
// If the label is not set, it returns an empty string.
func GetLabel(obj client.Object, key string) string {
	labels := obj.GetLabels()
	if labels == nil {
		return ""
	}
	return labels[key]
}

func mergeMaps(target, source map[string]string) map[string]string {
	if target == nil {
		return source
	}
	if source == nil {
		return target
	}
	for k, v := range source {
		target[k] = v
	}
	return target
}

// MergeMetadata merges source object's labels and annotations into target object
func MergeMetadata(target *metav1.ObjectMeta, source metav1.ObjectMeta) {
	target.Labels = mergeMaps(target.Labels, source.Labels)
	target.Annotations = mergeMaps(target.Annotations, source.Annotations)
}
