// Package grpc add by blacknc <blacknc@163.com> at 2023/01/03 17:15:46
package grpc

import (
	"context"
	"dataservices/commons/config"
	comErrs "dataservices/commons/errs"
	"dataservices/commons/utils"
	"fmt"
	"sync"

	"github.com/tidbcloud/account/idl/pbgen/proto/acl"
	"github.com/tidbcloud/tiinf/errs"
	tigrpc "github.com/tidbcloud/tiinf/transport/tigrpc/client"
)

var (
	accountAclSvcOnce sync.Once
	accountAclSvcCli  acl.AccessServiceClient
)

const (
	CodeClusterNotSupportDbuser = 60200004
)

func getAccountAclSvcClient() acl.AccessServiceClient {
	accountAclSvcOnce.Do(func() {
		conn, err := tigrpc.NewClientConn(config.Global().GrpcConf.AccountAclSvcAddr, tigrpc.WithDefault())
		if err != nil {
			panic(fmt.Sprintf("dial account-acl-grpc: %s", err))
		}

		accountAclSvcCli = acl.NewAccessServiceClient(conn)
	})

	return accountAclSvcCli
}

func GetJwtByToken(ctx context.Context, req *acl.GetJwtByTokenReq) (*acl.GetJwtByTokenResp, error) {
	client := getAccountAclSvcClient()

	resp, err := client.GetJwtByToken(ctx, req)
	if err != nil {
		err = errs.NewInternalGRPC(utils.GetFuncName(), err)
		return nil, err
	}
	if resp.BaseResp.ErrCode == CodeClusterNotSupportDbuser {
		return nil, comErrs.ErrClusterNotSupportDbUser
	}
	if err = formatError(ctx, err, resp.BaseResp); err != nil {
		return nil, err
	}
	if resp.Jwt == "" || resp.DbUser == "" {
		return nil, comErrs.ErrClusterUserJwtEmpty
	}
	return resp, nil
}

func GetJwtByApiKey(ctx context.Context, req *acl.GetJwtByApiKeyReq) (*acl.GetJwtByApiKeyResp, error) {
	client := getAccountAclSvcClient()

	resp, err := client.GetJwtByApiKey(ctx, req)
	if err != nil {
		err = errs.NewInternalGRPC(utils.GetFuncName(), err)
		return nil, err
	}
	if resp.BaseResp.ErrCode == CodeClusterNotSupportDbuser {
		return nil, comErrs.ErrClusterNotSupportDbUser
	}
	if err = formatError(ctx, err, resp.BaseResp); err != nil {
		return nil, err
	}
	if resp.Jwt == "" || resp.DbUser == "" {
		return nil, comErrs.ErrClusterUserJwtEmpty
	}
	return resp, nil
}

func GetJwtByUser(ctx context.Context, req *acl.GetJwtByUserReq) (*acl.GetJwtByUserResp, error) {
	client := getAccountAclSvcClient()

	resp, err := client.GetJwtByUser(ctx, req)
	if err != nil {
		err = errs.NewInternalGRPC(utils.GetFuncName(), err)
		return nil, err
	}
	if resp.BaseResp.ErrCode == CodeClusterNotSupportDbuser {
		return nil, comErrs.ErrClusterNotSupportDbUser
	}
	if err = formatError(ctx, err, resp.BaseResp); err != nil {
		return nil, err
	}
	if resp.Jwt == "" || resp.DbUser == "" {
		return nil, comErrs.ErrClusterUserJwtEmpty
	}
	return resp, nil
}
