package clusterconfig

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/sercand/kuberesolver/v5"
	configcenter "github.com/tidbcloud/config-center/proto/config_center"
	tigrpc "github.com/tidbcloud/tiinf/transport/tigrpc/client"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/clusterconfig"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/pkg/config"
	grpcutil "github.com/tidbcloud/tidb-management-service/utilities/grpc"
)

type configClientImpl struct {
	configCenterCli configcenter.ConfigCenterServiceClient
}

func NewConfigClient(cfg *config.Config) (clusterconfig.Client, error) {
	if cfg.ServerConfig.DependentSvcAddresses.ConfigCenterAddr == "" {
		return nil, errors.New("deprecated: config center client is not available in local mode")
	}

	clusterConfigCli, err := getConfigCenterClient(cfg)
	if err != nil {
		return nil, err
	}

	return &configClientImpl{
		configCenterCli: clusterConfigCli,
	}, nil
}

func getConfigCenterClient(cfg *config.Config) (configcenter.ConfigCenterServiceClient, error) {
	addr := cfg.ServerConfig.DependentSvcAddresses.ConfigCenterAddr
	timeoutMs := cfg.ServerConfig.DependentSvcAddresses.WaitTimeoutInMilliSec
	opts := []tigrpc.Option{
		tigrpc.WithPrometheus(),
		tigrpc.WithTracing(),
		tigrpc.WithUnaryInterceptors(
			grpcutil.TimeoutInterceptor(time.Duration(timeoutMs)*time.Millisecond),
			grpcutil.ClientPayloadLogInterceptor,
		),
	}
	if strings.HasPrefix(addr, "kubernetes://") {
		kuberesolver.RegisterInCluster()
		opts = append(opts, tigrpc.WithLoadBalance())
	}
	conn, err := tigrpc.NewClientConn(addr, opts...)
	if err != nil {
		return nil, fmt.Errorf("failed to create connection to config center: %w", err)
	}

	configCenterCli := configcenter.NewConfigCenterServiceClient(conn)

	return configCenterCli, nil
}
