package utils

import (
	"context"
	"errors"
	"fmt"
	"strconv"
	"tcidm/commons/config"
	"tcidm/commons/http/tidb_management_service"
	"tcidm/metrics"
	"time"

	regionalpb "github.com/tidbcloud/tidb-management-service/api/spec/regional/dedicated/v1"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

// @Time    : 2024/9/6 15:50
// @Author  : lvhongmeng

func GetDataflowAgentUrl(ctx context.Context, clusterId uint64) (agentUrl string, err error) {
	startTime := time.Now()
	defer func() {
		cost := time.Since(startTime).Milliseconds()
		ok := strconv.FormatBool(err == nil)
		metrics.DownstreamRequestDuration.WithLabelValues("dedicated-regional-server", "get_dataflow_agent_url", ok).Observe(float64(cost))
	}()

	regionalHost := config.Global().ServerConfig.TiDBManagementServiceEndpoint
	clusterServiceHTTPClient := tidb_management_service.NewClusterServiceHTTPClient(regionalHost)
	tilog.Info(ctx, "GetDataflowAgentUrl param", zap.String("regionalHost", regionalHost), zap.Any("clusterServiceHTTPClient", clusterServiceHTTPClient), zap.Uint64("clusterId", clusterId))

	cluster, err := clusterServiceHTTPClient.GetCluster(ctx, &regionalpb.GetClusterRequest{ClusterId: strconv.FormatUint(clusterId, 10)})
	if err != nil {
		tilog.Error(ctx, "GetDataflowAgentUrl-GetCluster failed", zap.Error(err))
		return "", err
	}
	tilog.Info(ctx, "GetDataflowAgentUrl-GetCluster success", zap.Uint64("clusterId", clusterId), zap.Any("response", cluster))

	appBoxServiceHTTPClient := tidb_management_service.NewAppBoxServiceHTTPClient(regionalHost)
	appBoxes, err := appBoxServiceHTTPClient.ListAppBoxes(ctx, &regionalpb.ListAPPBoxesRequest{TenantId: cluster.TenantId, ProjectId: cluster.ProjectId, ClusterId: cluster.Id})
	if err != nil {
		return "", err
	}
	if len(appBoxes.Appboxes) > 0 {
		tilog.Info(ctx, "GetDataflowAgentUrl-ListAppBoxes success", zap.Uint64("clusterId", clusterId), zap.Any("response", appBoxes))
		return appBoxes.Appboxes[0].DataflowAgentUrl, nil
	} else {
		tilog.Error(ctx, "GetDataflowAgentUrl-ListAppBoxes empty")
		return "", errors.New(fmt.Sprintf("Appbox not exist! tenantId:%s,projectId:%s,clusterId:%s", cluster.TenantId, cluster.ProjectId, cluster.Id))
	}
}

func GetAWSExternalId(ctx context.Context, clusterId uint64) (string, error) {
	if config.Global().ServerConfig.Provider != "eks" {
		return "", nil
	}

	regionalHost := config.Global().ServerConfig.TiDBManagementServiceEndpoint
	clusterServiceHTTPClient := tidb_management_service.NewClusterServiceHTTPClient(regionalHost)
	tilog.Info(ctx, "GetAWSExternalId param", zap.String("regionalHost", regionalHost), zap.Any("clusterServiceHTTPClient", clusterServiceHTTPClient), zap.Uint64("clusterId", clusterId))

	clusterRole, err := clusterServiceHTTPClient.GetClusterRole(ctx, &regionalpb.GetClusterRoleRequest{ClusterId: strconv.FormatUint(clusterId, 10)})
	if err != nil {
		tilog.Error(ctx, "GetAWSExternalId-GetClusterRole failed", zap.Uint64("clusterId", clusterId), zap.Error(err))
		return "", err
	}
	tilog.Info(ctx, "GetAWSExternalId-GetClusterRole success", zap.Uint64("clusterId", clusterId), zap.Any("response", clusterRole))

	return clusterRole.ExternalId, nil
}

func GetClusterRole(ctx context.Context, clusterId uint64) (*regionalpb.ClusterRole, error) {

	regionalHost := config.Global().ServerConfig.TiDBManagementServiceEndpoint
	clusterServiceHTTPClient := tidb_management_service.NewClusterServiceHTTPClient(regionalHost)
	tilog.Info(ctx, "GetAWSExternalId param", zap.String("regionalHost", regionalHost), zap.Any("clusterServiceHTTPClient", clusterServiceHTTPClient), zap.Uint64("clusterId", clusterId))

	clusterRole, err := clusterServiceHTTPClient.GetClusterRole(ctx, &regionalpb.GetClusterRoleRequest{ClusterId: strconv.FormatUint(clusterId, 10)})
	if err != nil {
		tilog.Error(ctx, "GetAWSExternalId-GetClusterRole failed", zap.Uint64("clusterId", clusterId), zap.Error(err))
		return nil, err
	}
	tilog.Info(ctx, "GetAWSExternalId-GetClusterRole success", zap.Uint64("clusterId", clusterId), zap.Any("response", clusterRole))
	return clusterRole, nil
}
