package gardener

import (
	"context"
	"fmt"
	"hash/fnv"

	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes"
	restclient "k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

type Cloud string

const (
	gardenNamespace                = "garden"
	gardenKubeconfigForAdmin       = "garden-kubeconfig-for-admin"
	CloudAWS                 Cloud = "aws"
	CloudGCP                 Cloud = "gcp"
)

// NewGardenerClient new kubernetes client-set in gardener cluster
func NewGardenerClientSet(baseCli client.Client) (kubernetes.Interface, error) {
	secret := &v1.Secret{}
	ctx := context.Background()
	err := baseCli.Get(ctx, types.NamespacedName{
		Namespace: gardenNamespace,
		Name:      gardenKubeconfigForAdmin,
	}, secret)
	if err != nil {
		return nil, err
	}
	restConfig, err := RestConfigFromSecret(secret)
	if err != nil {
		return nil, err
	}

	return kubernetes.NewForConfig(restConfig)
}

func RestConfigFromSecret(secret *v1.Secret) (*restclient.Config, error) {
	return clientcmd.RESTConfigFromKubeConfig(secret.Data["kubeconfig"])
}

func ShootName(tenant string, cloud Cloud, region string) string {
	rawName := fmt.Sprintf("%s-%s-%s", tenant, cloud, region)
	return FnvHash(rawName)
}

func FnvHash(raw string) string {
	hash := fnv.New32()
	if _, err := hash.Write([]byte(raw)); err != nil {
		return ""
	}
	return fmt.Sprintf("%x", hash.Sum32())
}
