package cmek

import (
	"context"
	"errors"

	"gorm.io/gorm"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *customerManagedEncryptionKeyServiceImpl) Delete(
	ctx context.Context,
	req *globaldedicatedv1.DeleteCustomerManagedEncryptionKeyRequest,
) bizerr.BizError {
	ctx, span := Tracer.Start(ctx, "Domain.DeleteCmek")
	defer span.End()

	err := s.transaction.Transaction(ctx, func(ctx context.Context) error {
		cmek, err := s.cmekRepo.Get(ctx, req.CustomerManagedEncryptionKeyId)
		if err != nil {
			return err
		}

		// check if cmek is used by cluster
		clusters, err := s.clusterRepo.Query(ctx, &cluster.Filter{CmekIds: []uint64{cmek.Id}})
		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
			return err
		}

		if len(clusters) > 0 {
			return bizerr.New(bizerr.ErrCodePermission, "cmek %d is in use", cmek.Id)
		}

		if err := s.cmekRepo.Delete(ctx, cmek.Id); err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		var e bizerr.BizError
		if errors.As(err, &e) {
			if e.ErrCode() == bizerr.ErrCodeRecordNotFound {
				return bizerr.New(bizerr.ErrCodeRecordNotFound, "cmek %d not found", req.CustomerManagedEncryptionKeyId)
			}
			if e.ErrCode() == bizerr.ErrCodePermission {
				return e
			}
		}

		return bizerr.New(bizerr.ErrCodeDB, "%s", err.Error())
	}

	return nil
}
