package cmek

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"
	"go.opentelemetry.io/otel"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/account"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/regionserver"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	clusterrepo "github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cmek"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/featuregate"
	"github.com/tidbcloud/tidb-management-service/utilities/idgenerator"
)

var (
	Tracer = otel.Tracer("domain.cmek")
)

type CustomerManagedEncryptionKeyService interface {
	Create(
		ctx context.Context,
		req *globaldedicatedv1.CreateCustomerManagedEncryptionKeyRequest,
	) (*entity.CustomerManagedEncryptionKey, bizerr.BizError)
	Get(
		ctx context.Context,
		req *globaldedicatedv1.GetCustomerManagedEncryptionKeyRequest,
	) (*entity.CustomerManagedEncryptionKey, bizerr.BizError)
	List(
		ctx context.Context,
		req *globaldedicatedv1.ListCustomerManagedEncryptionKeysRequest,
	) ([]*entity.CustomerManagedEncryptionKey, bizerr.BizError)
	Delete(ctx context.Context, req *globaldedicatedv1.DeleteCustomerManagedEncryptionKeyRequest) bizerr.BizError
	GetCmekAccessIamPrincipal(
		ctx context.Context,
		req *globaldedicatedv1.GetCmekAccessIamPrincipalRequest,
	) (*entity.CmekAccessIamPrincipal, bizerr.BizError)
}

type customerManagedEncryptionKeyServiceImpl struct {
	cmekRepo           cmek.Repo
	clusterRepo        clusterrepo.Repo
	regionRepo         region.Repo
	regionServerCli    regionserver.Client
	idGeneratorAdapter idgenerator.IDGenerator
	accountCli         account.Client
	featGateCli        featuregate.Service
	transaction        db.Transactioner
}

func NewService(
	cmekRepo cmek.Repo,
	clusterRepo clusterrepo.Repo,
	regionRepo region.Repo,
	regionServerCli regionserver.Client,
	idGeneratorAdapter idgenerator.IDGenerator,
	accountCli account.Client,
	featGateCli featuregate.Service,
	transaction db.TransProvider,
) CustomerManagedEncryptionKeyService {
	return &customerManagedEncryptionKeyServiceImpl{
		cmekRepo:           cmekRepo,
		clusterRepo:        clusterRepo,
		regionRepo:         regionRepo,
		regionServerCli:    regionServerCli,
		idGeneratorAdapter: idGeneratorAdapter,
		accountCli:         accountCli,
		featGateCli:        featGateCli,
		transaction:        transaction,
	}
}
