package acl

import (
	"context"
	"fmt"
	"sync"

	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	tigrpc "github.com/tidbcloud/tiinf/transport/tigrpc/client"
	"go.uber.org/zap"
	"google.golang.org/grpc"

	"github.com/tidbcloud/account/idl/pbgen/proto/acl"

	"github.com/tidbcloud/auditlog/configs"
)

var (
	aclInitOnce sync.Once
	aclSvc      AclSvcIface
)

type AclSvcIface interface {
	GetOpenAPIKeyByToken(ctx context.Context, toke string) (*acl.GetOpenAPIKeyByTokenResp, error)
}

func NewAclSvcIface(ctx context.Context, cfg *configs.Config) AclSvcIface {
	aclInitOnce.Do(func() {
		var conn *grpc.ClientConn
		conn, err := tigrpc.NewClientConn(cfg.ACLSvcAddr, tigrpc.WithDefault())
		tilog.Info(ctx, "Initializing account service client", zap.Any("err", err), zap.String("addr", cfg.AccountSvcAddr))
		if err != nil {
			panic(fmt.Sprintf("dial account-svc: %s", err))
		}

		aclClient := acl.NewAccessServiceClient(conn)
		aclSvc = &aclSvcImpl{aclClient}
	})

	return aclSvc
}

type aclSvcImpl struct {
	aclClient acl.AccessServiceClient
}

func (a *aclSvcImpl) GetOpenAPIKeyByToken(ctx context.Context, pubKey string) (*acl.GetOpenAPIKeyByTokenResp, error) {
	req := &acl.GetOpenAPIKeyByTokenReq{PublicKey: pubKey}
	aclResp, err := a.aclClient.GetOpenAPIKeyByToken(ctx, req)
	if err != nil {
		return nil, errs.NewInternalGRPC("GetClusterByID", err)
	}

	return aclResp, nil
}
