package cmek

import (
	"context"

	"go.opentelemetry.io/otel"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	openapingv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/nextgen/v1beta2"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/app/openapi/nextgen/common"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/nextgenglobal"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/grpc/metadata"
)

var tracer = otel.Tracer("App.NextGen.Cmek")

type serverImpl struct {
	nextgenCli nextgenglobal.NextGenGlobal
}

func NewServer(
	nextgenCli nextgenglobal.NextGenGlobal,
) openapingv1beta2.CustomerManagedEncryptionKeyServiceServer {
	return &serverImpl{
		nextgenCli: nextgenCli,
	}
}

func (s *serverImpl) ListCustomerManagedEncryptionKeys(
	ctx context.Context,
	req *openapingv1beta2.ListCustomerManagedEncryptionKeysRequest,
) (*openapingv1beta2.ListCustomerManagedEncryptionKeysResponse, error) {
	ctx, span := tracer.Start(ctx, "ListCustomerManagedEncryptionKeys")
	defer span.End()

	reqMeta, err := metadata.ExtractRequestMetaWithCheckPermission(ctx)
	if err != nil {
		return nil, bizerr.WrapErrorWithCode(err, bizerr.ErrCodeParams, "failed to extract request metadata")
	}

	globalReq := &globalngv1.ListCustomerManagedEncryptionKeysRequest{
		OrganizationId: reqMeta.OrgID,
	}

	globalResp, err := s.nextgenCli.ListCustomerManagedEncryptionKeys(ctx, globalReq)
	if err != nil {
		return nil, err
	}

	var keys []*openapingv1beta2.CustomerManagedEncryptionKey
	for _, gk := range globalResp.GetCustomerManagedEncryptionKeys() {
		k, convErr := common.CvtGlobalCmekToOpenapi(gk)
		if convErr != nil {
			return nil, convErr
		}
		keys = append(keys, k)
	}

	return &openapingv1beta2.ListCustomerManagedEncryptionKeysResponse{
		CustomerManagedEncryptionKeys: keys,
	}, nil
}
