package agentcontrolutils

import (
	"context"
	"fmt"

	regionalpb "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	"github.com/tidbcloud/infra-provider/pkg/consts"
	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	agentcontrolapi "github.com/tidbcloud/observability/agent-control-server/pkg/agentcontrol/api"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

func BuildDataplaneConfig(ctx context.Context, cli client.Client, appbox *v1alpha1.APPBox) (*agentcontrolapi.DataplaneConfig, error) {
	vpc := &v1alpha1.VPC{}
	if err := cli.Get(ctx, types.NamespacedName{
		Namespace: appbox.Spec.VPCRef.Namespace,
		Name:      appbox.Spec.VPCRef.Name},
		vpc); err != nil {
		return nil, fmt.Errorf("failed to get vpc: %w", err)
	}
	dataplaneCfg := &agentcontrolapi.DataplaneConfig{
		ClusterName: appbox.Status.KubernetesClusterName,
	}
	switch appbox.Spec.Provider {
	case consts.ProviderTypeEKS:
		subnetIDs := make([]string, 0, len(vpc.Status.NodeSubnets))
		for _, sn := range vpc.Status.NodeSubnets {
			subnetIDs = append(subnetIDs, sn.SubnetID)
		}
		dataplaneCfg.AWS = &agentcontrolapi.AWSConfig{
			VpcID:              vpc.Status.VPC.VPCID,
			AccountID:          vpc.Spec.AccountRef.AccountID,
			NodeSubnetIDs:      subnetIDs,
			SecurityGroupID:    vpc.Status.SecurityGroup.SecurityGroupID,
			AssumeRoleArn:      fmt.Sprintf("arn:aws:iam::%s:role/%s", vpc.Spec.AccountRef.AccountID, vpc.Spec.AccountRef.Role),
			ProviderConfigName: vpc.Spec.AccountRef.ProviderConfigName,
		}
	case consts.ProviderTypeGKE:
		subnetNames := make([]string, 0, len(vpc.Status.NodeSubnets))
		for _, sn := range vpc.Status.NodeSubnets {
			subnetNames = append(subnetNames, sn.Name)
		}
		dataplaneCfg.GCP = &agentcontrolapi.GCPConfig{
			Network: vpc.Status.VPC.VPCID,
			Project: vpc.Spec.AccountRef.AccountID,
			Subnets: subnetNames,
		}
	case consts.ProviderTypeAKS:
		subnetID := ""
		if len(vpc.Status.NodeSubnets) > 0 {
			subnetID = vpc.Status.NodeSubnets[0].SubnetID
		}
		podSubnetID := ""
		if len(vpc.Status.PodSubnets) > 0 {
			podSubnetID = vpc.Status.PodSubnets[0].SubnetID
		}
		dataplaneCfg.Azure = &agentcontrolapi.AzureConfig{
			Network:            vpc.Status.VPC.VPCID,
			SubscriptionID:     vpc.Spec.AccountRef.AccountID,
			SubnetID:           subnetID,
			PodSubnetID:        podSubnetID,
			ResourceGroup:      vpc.Status.ResourceGroup.Name,
			ProviderConfigName: vpc.Spec.AccountRef.ProviderConfigName,
		}
	}
	return dataplaneCfg, nil
}

func BuildTiDBClusterTopology(cluster *regionalpb.Cluster) agentcontrolapi.TiDBClusterTopology {
	topo := agentcontrolapi.TiDBClusterTopology{}
	for _, c := range cluster.ComponentNodeSpecs {
		switch c.ComponentType {
		case regionalpb.ComponentType_TIDB:
			topo.TiDB = agentcontrolapi.TiDB{
				Replicas: int(c.Count),
			}
		case regionalpb.ComponentType_PD:
			topo.PD = agentcontrolapi.PD{
				Replicas: int(c.Count),
			}
		case regionalpb.ComponentType_TIKV:
			topo.TiKV = agentcontrolapi.TiKV{
				Replicas: int(c.Count),
			}
		case regionalpb.ComponentType_TIFLASH:
			topo.TiFlash = agentcontrolapi.TiFlash{
				Replicas: int(c.Count),
			}
		}
	}
	return topo
}
