package runtimeutil

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

	"github.com/pingcap/dbaas/central/db/entity"
	"github.com/pingcap/log"
	"go.uber.org/zap"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

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

func FnvHash(raw string) string {
	hash := fnv.New32()
	if _, err := hash.Write([]byte(raw)); err != nil {
		// impossible path
		log.Error("failed to write fnv hash", zap.Error(err))
	}
	return fmt.Sprintf("%x", hash.Sum32())
}

// GetGardenerKubeConfigFromBase get the gardner kubeconfig from base cluster
func GetGardenerKubeConfigFromBase(baseCli kubernetes.Interface) (*rest.Config, error) {
	secretName := "garden-kubeconfig-for-admin"
	gardenKubeConfigSecret, err := baseCli.CoreV1().Secrets("garden").Get(context.TODO(), secretName, metav1.GetOptions{})
	if err != nil {
		return nil, err
	}
	gardenKubeConfig, err := clientcmd.RESTConfigFromKubeConfig(gardenKubeConfigSecret.Data["kubeconfig"])
	if err != nil {
		return nil, err
	}
	return gardenKubeConfig, nil
}

// GetInfraAPIKubeConfigFromBase get the infra API server kubeconfig from the base cluster.
func GetInfraAPIKubeConfigFromBase(baseCli kubernetes.Interface) (*rest.Config, error) {
	secretNamespace := "infra"
	secretName := "api-server-kubeconfig"
	secret, err := baseCli.CoreV1().Secrets(secretNamespace).Get(context.TODO(), secretName, metav1.GetOptions{})
	if err != nil {
		return nil, err
	}
	kubeconfig, err := clientcmd.RESTConfigFromKubeConfig(secret.Data["config"])
	if err != nil {
		return nil, err
	}
	return kubeconfig, nil
}
