package privatelink

import (
	"context"
	"strconv"

	clusterdedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

// Create creates a private load balancer for the cluster's default work pool.
func (svc *service) CreateClusterConnection(ctx context.Context, clusterId uint64) bizerr.BizError {
	ctx, span := tracer.Start(ctx, "Domain.CreateClusterConnSvc")
	defer span.End()

	cluster, err := svc.clusterRepo.Get(ctx, clusterId, false)
	if err != nil {
		return err
	}
	if cluster.State != globaldedicatedv1.Cluster_AVAILABLE {
		return bizerr.New(bizerr.ErrCodeParams, "cluster state is not AVAILABLE")
	}

	region, err := svc.regionRepo.SelectRegionById(ctx, cluster.RegionId, cluster.OrganizationId)
	if err != nil {
		return err
	}

	tg, err := svc.tidbGroupRepo.LoadDefault(ctx, clusterId)
	if err != nil {
		return err
	}

	getTidbGroupRequest := &clusterdedicatedv1.GetTidbGroupRequest{
		ClusterId:   strconv.FormatUint(clusterId, 10),
		TidbGroupId: strconv.FormatUint(tg.Id, 10),
	}
	var tidbGroup *clusterdedicatedv1.TidbGroup
	tidbGroup, err = svc.regionServerCli.GetTidbGroup(ctx, region, getTidbGroupRequest)
	if err != nil {
		return err
	}
	if tidbGroup.EnablePrivateLb && tidbGroup.PrivateLb != nil {
		return bizerr.New(bizerr.ErrCodeParams, "cluster already has private type connection")
	}

	tidbGroup.EnablePrivateLb = true
	tidbGroup.PrivateLb = &clusterdedicatedv1.LoadBalancer{
		Host:            "", // leave it empty
		Port:            int32(cluster.Port),
		IpAllowList:     nil, // leave it empty
		CloudResourceId: "",  // leave it empty
	}
	updateTidbGroupRequest := &clusterdedicatedv1.UpdateTidbGroupRequest{
		ClusterId:   strconv.FormatUint(clusterId, 10),
		TidbGroupId: strconv.FormatUint(tg.Id, 10),
		TidbGroup:   tidbGroup,
	}
	_, err = svc.regionServerCli.UpdateTidbGroup(ctx, region, updateTidbGroupRequest)
	if err != nil {
		return err
	}

	return nil
}
