package grpc

import (
	"context"
	"fmt"
	"sync"

	"github.com/tidbcloud/core-svc/idl/pbgen/proto/core"
	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	tigrpc "github.com/tidbcloud/tiinf/transport/tigrpc/client"
	"go.buf.build/protocolbuffers/go/linuxgit/tidbcloud/base"
	"go.uber.org/zap"

	"github.com/tidbcloud/aipower/commons/config"
)

var (
	coreSvcOnce sync.Once
	coreSvcCli  core.CoreServiceClient
)

func parseInfraResp(baseResp *base.BaseResp) error {
	if baseResp.ErrCode == errs.ErrCodeOK {
		return nil
	}

	return errs.NewInternalServerError("infra server error", nil)
}

func GetCoreSvcClient() core.CoreServiceClient {
	addr := config.Global().GrpcConf.CoreSvcAddr
	coreSvcOnce.Do(func() {
		conn, err := tigrpc.NewClientConn(addr, tigrpc.WithDefault())
		if err != nil {
			panic(fmt.Sprintf("dial core-svc: %s", err))
		}

		coreSvcCli = core.NewCoreServiceClient(conn)
		tilog.Info(context.Background(), "Initializing core service client", zap.String("addr", addr), zap.Any("err", err))
	})

	return coreSvcCli
}

func GetClusterByID(ctx context.Context, clusterID uint64) (*core.Cluster, error) {
	client := GetCoreSvcClient()

	req := &core.ListClustersReq{
		Filter: &core.ClusterFilter{
			ClusterIds: []uint64{clusterID},
			Statuses:   []core.ClusterStatus{core.ClusterStatus_CLUSTER_STATUS_NORMAL},
		},
	}
	resp, e := client.ListClusters(ctx, req)
	if e != nil {
		return nil, errs.NewInternalGRPC("GetProjectClustersInStatus", e)
	}

	if err := parseInfraResp(resp.BaseResp); err != nil {
		return nil, err
	}

	var cluster *core.Cluster
	for _, i := range resp.OrderedClusterIds {
		if i == clusterID {
			cluster = resp.Clusters[i]
		}
	}

	return cluster, nil
}
