package service

import (
	"context"
	"tcidm/commons/http/agent"
	"tcidm/internal/service/utils"
	"time"

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

// @Time    : 2024/8/21 15:19
// @Author  : lvhongmeng

func CheckS3Access(ctx context.Context, clusterId uint64, timeout int64, req *dataflowgprc.CheckS3AccessReq) (*dataflowgprc.CheckS3AccessResp, error) {
	dataflowAgentUrl, err := utils.GetDataflowAgentUrl(ctx, clusterId)
	if err != nil {
		tilog.Error(ctx, "failed to get dataflow agent url", zap.Error(err))
		return nil, err
	}
	agentClient, err := agent.GetAgentClient(ctx, dataflowAgentUrl)
	agentClient.SetHttpTimeout(time.Duration(timeout) * time.Millisecond)
	if err != nil {
		tilog.Error(ctx, "failed to get agent client", zap.Error(err))
		return nil, err
	}
	if req.ExternalId == "" {
		awsExternalId, err := utils.GetAWSExternalId(ctx, clusterId)
		if err != nil {
			tilog.Error(ctx, "failed to get aws external id", zap.Error(err))
			return nil, err
		}
		req.ExternalId = awsExternalId
	}
	resp, err := agentClient.CheckS3Access(ctx, req)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "CheckS3Access resp", zap.Any("resp", resp))
	return resp, nil
}

func CheckGcsAccess(ctx context.Context, clusterId uint64, timeout int64, req *dataflowgprc.CheckGcsAccessReq) (*dataflowgprc.CheckGcsAccessResp, error) {
	dataflowAgentUrl, err := utils.GetDataflowAgentUrl(ctx, clusterId)
	if err != nil {
		tilog.Error(ctx, "failed to get dataflow agent url", zap.Error(err))
		return nil, err
	}
	agentClient, err := agent.GetAgentClient(ctx, dataflowAgentUrl)
	agentClient.SetHttpTimeout(time.Duration(timeout) * time.Millisecond)
	if err != nil {
		tilog.Error(ctx, "failed to get agent client", zap.Error(err))
		return nil, err
	}
	resp, err := agentClient.CheckGcsAccess(ctx, req)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "CheckGcsAccess resp", zap.Any("resp", resp))
	return resp, nil
}

func CheckAzblobAccess(ctx context.Context, clusterId uint64, timeout int64, req *dataflowgprc.CheckAzblobAccessReq) (*dataflowgprc.CheckAzblobAccessResp, error) {
	dataflowAgentUrl, err := utils.GetDataflowAgentUrl(ctx, clusterId)
	if err != nil {
		tilog.Error(ctx, "failed to get dataflow agent url", zap.Error(err))
		return nil, err
	}
	agentClient, err := agent.GetAgentClient(ctx, dataflowAgentUrl)
	agentClient.SetHttpTimeout(time.Duration(timeout) * time.Millisecond)
	if err != nil {
		tilog.Error(ctx, "failed to get agent client", zap.Error(err))
		return nil, err
	}
	resp, err := agentClient.CheckAzblobAccess(ctx, req)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "CheckAzblobAccess resp", zap.Any("resp", resp))
	return resp, nil
}

func GetClusterTables(ctx context.Context, clusterId uint64, timeout int64, req *dataflowgprc.Cluster) (*dataflowgprc.GetClusterTablesResp, error) {
	dataflowAgentUrl, err := utils.GetDataflowAgentUrl(ctx, clusterId)
	if err != nil {
		tilog.Error(ctx, "failed to get dataflow agent url", zap.Error(err))
		return nil, err
	}
	agentClient, err := agent.GetAgentClient(ctx, dataflowAgentUrl)
	agentClient.SetHttpTimeout(time.Duration(timeout) * time.Millisecond)
	if err != nil {
		tilog.Error(ctx, "failed to get agent client", zap.Error(err))
		return nil, err
	}
	resp, err := agentClient.GetClusterTables(ctx, req)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "GetClusterTables resp", zap.Any("resp", resp))
	return resp, nil
}

func ExecSQLOnCluster(ctx context.Context, clusterId uint64, timeout int64, req *dataflowgprc.ExecSQLReq) (*dataflowgprc.ExecSQLResp, error) {
	dataflowAgentUrl, err := utils.GetDataflowAgentUrl(ctx, clusterId)
	if err != nil {
		tilog.Error(ctx, "failed to get dataflow agent url", zap.Error(err))
		return nil, err
	}
	agentClient, err := agent.GetAgentClient(ctx, dataflowAgentUrl)
	agentClient.SetHttpTimeout(time.Duration(timeout) * time.Millisecond)
	if err != nil {
		tilog.Error(ctx, "failed to get agent client", zap.Error(err))
		return nil, err
	}
	resp, err := agentClient.ExecSQLOnCluster(ctx, req)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "ExecSQLOnCluster resp", zap.Any("resp", resp))
	return resp, nil
}

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