package cluster

import (
	"fmt"

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

func (r *reconcileContext) SubResourceLabels() map[string]string {
	return map[string]string{
		consts.ClusterNamespaceLabelKey: r.Target.Namespace,
		consts.ClusterNameLabelKey:      r.Target.Name,
		cloudv1.ProviderTypeLabel:       r.ProviderType,
	}
}

func (r *reconcileContext) publicDnsRecordName() string {
	return fmt.Sprintf("%s-public", r.Target.ClusterScopeName())
}

func (r *reconcileContext) privateDnsRecordName() string {
	return fmt.Sprintf("%s-private", r.Target.ClusterScopeName())
}

func (r *reconcileContext) privatelinkDnsRecordName() string {
	return fmt.Sprintf("%s-privatelink", r.Target.ClusterScopeName())
}

func (r *reconcileContext) publicEndpointAddress() string {
	if isUseLegacyDNS(r.Target) {
		return r.legacyPublicEndpointAddress()
	}

	return PublicEndpointAddress(r.Target, r.publicHostedZoneDomain)
}

func (r *reconcileContext) legacyPublicEndpointAddress() string {
	baseDomain := r.providerGardenerSpec.AWS.PublicHostedZoneDomain
	if r.Provider.Spec.Type == consts.ProviderTypeGCP {
		baseDomain = r.providerGardenerSpec.GCP.PublicHostedZoneDomain
	}
	return LegacyPublicEndpointAddress(r.Network, r.Target, baseDomain)
}

func PublicEndpointAddress(cluster *cloudv1.Cluster, publicHostedZoneDomain string) string {
	return fmt.Sprintf("%s.%s.%s", "tidb", cluster.Spec.SqlEndpoints.DNS.Identity, publicHostedZoneDomain)
}

func LegacyPublicEndpointAddress(network *cloudv1.Network, cluster *cloudv1.Cluster, publicHostedZoneDomain string) string {
	clusterIdHash := util.FnvHash(cluster.PrefixedId())
	networkIdHash := util.FnvHash(network.GetProjectId())
	if tenantID, ok := cluster.GetAnnotations()[cloudv1.LegacyTenantIdAnno]; ok {
		// for legacy cluster, there is a bug that the endpoint is still using tenantID, keep compatibility with the bug
		networkIdHash = util.FnvHash(tenantID)
	}
	region := network.Spec.Region
	baseDomain := publicHostedZoneDomain
	// Currently we only support TiDB service endpoint
	// In the future we may support TiKV service endpoint
	serviceName := "tidb"

	return fmt.Sprintf("%s.%s.%s.%s.%s", serviceName, clusterIdHash, networkIdHash, region, baseDomain)
}

func (r *reconcileContext) HostedZoneDomain() string {
	if isUseLegacyDNS(r.Target) {
		baseDomain := r.providerGardenerSpec.AWS.PublicHostedZoneDomain
		if r.Provider.Spec.Type == consts.ProviderTypeGCP {
			baseDomain = r.providerGardenerSpec.GCP.PublicHostedZoneDomain
		}
		region := r.Network.Spec.Region
		return fmt.Sprintf("%s.%s", region, baseDomain)
	}

	return r.publicHostedZoneDomain
}

func (r *reconcileContext) HostedZoneID() string {
	if isUseLegacyDNS(r.Target) {
		zoneID := r.providerGardenerSpec.AWS.PublicHostedZoneId
		if r.Provider.Spec.Type == consts.ProviderTypeGCP {
			zoneID = r.providerGardenerSpec.GCP.PublicHostedZoneId
		}
		return zoneID
	}

	return r.publicHostedZoneID
}
