package cmek

import (
	"context"

	coreapi "github.com/tidbcloud/core-svc/idl/pbgen/proto/core"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/protobuf/proto"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	cmeksvc "github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/service/cmek"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/enum"
)

type CreateCmekSvc struct {
	cmekSvc cmeksvc.CustomerManagedEncryptionKeyService
}

func NewCreateCmekSvc(cmekSvc cmeksvc.CustomerManagedEncryptionKeyService) *CreateCmekSvc {
	return &CreateCmekSvc{
		cmekSvc: cmekSvc,
	}
}

func (svc *CreateCmekSvc) Create(ctx context.Context, req *coreapi.CreateAwsCmekReq) bizerr.BizError {
	logger := tilog.WithContextS(ctx).With(zap.Uint64("projectID", req.ProjectId), zap.Uint64("OrgID", req.OrgId))

	cmekReq := &globaldedicatedv1.CreateCustomerManagedEncryptionKeyRequest{
		ValidateOnly: false,
		CustomerManagedEncryptionKey: &globaldedicatedv1.CustomerManagedEncryptionKey{
			OrganizationId:  req.OrgId,
			ProjectId:       req.ProjectId,
			CloudProviderId: globalcommonv1.CloudProvider_AWS,
		},
	}

	for _, cmek := range req.Specs {
		cmekCreateReq, ok := proto.Clone(cmekReq).(*globaldedicatedv1.CreateCustomerManagedEncryptionKeyRequest)
		if !ok {
			return bizerr.New(bizerr.ErrCodeUnknown, "failed to clone cmek request")
		}

		// get region id
		cloudRegionId, err := enum.FromString[globalcommonv1.Region_Name](cmek.RegionName)
		if err != nil {
			return bizerr.New(bizerr.ErrCodeParams, "region %s is not supported", cmek.RegionName)
		}
		cmekCreateReq.CustomerManagedEncryptionKey.RegionId = globalcommonv1.Region_Name(cloudRegionId)

		// full kms arn
		cmekCreateReq.CustomerManagedEncryptionKey.MasterKey = &globaldedicatedv1.CustomerManagedEncryptionKey_AwsKeyArn{
			AwsKeyArn: cmek.KmsArn,
		}

		_, berr := svc.cmekSvc.Create(ctx, cmekCreateReq)
		if berr != nil {
			return berr
		}
	}

	logger.Infof("create cmek processed")
	return nil
}
