package privatelink

import (
	"context"
	"strconv"

	regionaldedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/regionserver"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (svc *service) GetPrivateLinkService(
	ctx context.Context,
	request *globaldedicatedv1.GetPrivateLinkServiceRequest,
) (*globaldedicatedv1.PrivateLinkService, bizerr.BizError) {
	cluster, err := svc.clusterRepo.Get(ctx, request.ClusterId, false)
	if err != nil {
		return nil, err
	}

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

	tidbGroup, err := svc.tidbGroupRepo.LoadDefault(ctx, request.ClusterId)
	if err != nil {
		return nil, err
	}

	getPrivateLinkServiceRequest := &regionserver.GetPrivateLinkServiceRequest{
		ClusterId:   strconv.FormatUint(cluster.ClusterId, 10),
		TidbGroupId: strconv.FormatUint(tidbGroup.Id, 10),
	}
	privateLinkService, err := svc.regionServerCli.GetPrivateLinkService(ctx, region, getPrivateLinkServiceRequest)
	if err != nil {
		return nil, err
	}

	return privateLinkServiceRegionalToGlobal(privateLinkService, cluster), nil
}

func privateLinkServiceRegionalToGlobal(
	privateLinkService *regionaldedicatedv1.PrivateLinkService,
	cluster *entity.Cluster,
) *globaldedicatedv1.PrivateLinkService {
	out := &globaldedicatedv1.PrivateLinkService{
		Name:    "", // fill later
		Status:  privateLinkServiceStatusRegionalToGlobal(privateLinkService),
		DnsName: privateLinkService.GetServiceDnsName(),
		AzIds:   nil, // fill later
	}

	if out.GetDnsName() == "" {
		out.DnsName = privateLinkService.GetHost()
	}

	switch cluster.GetCloudProviderId() {
	case globalcommonv1.CloudProvider_AWS:
		out.Name = privateLinkService.GetAws().GetServiceName()
		out.AzIds = privateLinkService.GetAws().GetAzIds()
	case globalcommonv1.CloudProvider_GCP:
		out.Name = privateLinkService.GetGcp().GetServiceAttachment()
	case globalcommonv1.CloudProvider_AZURE:
		out.Name = privateLinkService.GetAzure().GetServiceResourceId()
	}

	return out
}

func privateLinkServiceStatusRegionalToGlobal(
	privateLinkService *regionaldedicatedv1.PrivateLinkService,
) globaldedicatedv1.PrivateLinkService_Status {
	switch privateLinkService.GetStatus() {
	case regionaldedicatedv1.PrivateLinkService_CREATING:
		return globaldedicatedv1.PrivateLinkService_CREATING
	case regionaldedicatedv1.PrivateLinkService_ACTIVE:
		return globaldedicatedv1.PrivateLinkService_ACTIVE
	case regionaldedicatedv1.PrivateLinkService_DELETING:
		return globaldedicatedv1.PrivateLinkService_DELETING
	default:
		return globaldedicatedv1.PrivateLinkService_STATUS_UNSPECIFIED
	}
}
