package cluster

import (
	"os"
	"strings"

	"github.com/pingcap/errors"
	"github.com/tidbcloud/aws-shared-provider/pkg/types"
	"github.com/tidbcloud/aws-shared-provider/pkg/utils"
	infra "github.com/tidbcloud/tidb-management-service/api/serverless_infra"
	corev1 "k8s.io/api/core/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
	defaultTiDBPort = 4000
)

func (r *reconcileContext) reconcileCluster() error {
	var reqErrs error
	if err := utils.IgnoreRequeue(&reqErrs, r.reconcileServerless()); err != nil {
		return err
	}

	if err := r.observeCluster(); err != nil {
		return err
	}
	return reqErrs
}

func (r *reconcileContext) genPublicEndpointStatus() (*infra.PublicStatus, error) {
	gateway := &corev1.Service{}
	if err := r.Client.Get(
		r.ctx, client.ObjectKey{
			Name:      "tidb-gateway-new",
			Namespace: os.Getenv("NAMESPACE"),
		}, gateway,
	); err != nil {
		return nil, err
	}
	dnsName := gateway.Annotations[types.AnnoGatewayDnsName]
	if dnsName == "" {
		return nil, errors.New("can't found tidb-gateway service's dnsName")
	}

	return &infra.PublicStatus{
		Host: dnsName,
		Port: defaultTiDBPort,
	}, nil
}

func (r *reconcileContext) genPrivatelinkStatus() (*infra.AwsPrivatelinkServiceStatus, error) {
	privatelinkServiceConfig := "privatelink-service-config"
	if r.cluster.Spec.EnableZoneRedundant == "yes" && r.ProviderType != types.ProviderTypeAliCloudFreeTier {
		privatelinkServiceConfig = "privatelink-zr-service-config"
	}

	privatelink := &corev1.ConfigMap{}
	if err := r.Client.Get(
		r.ctx, client.ObjectKey{
			Name:      privatelinkServiceConfig,
			Namespace: os.Getenv("NAMESPACE"),
		}, privatelink,
	); err != nil {
		return nil, err
	}

	return &infra.AwsPrivatelinkServiceStatus{
		AvailabilityZones: strings.Split(privatelink.Data["availability-zones"], ","),
		ServiceName:       privatelink.Data["service-name"],
		PrivateDnsName:    privatelink.Data["private-dns"],
		Port:              defaultTiDBPort,
	}, nil
}
