package cmek

import (
	"context"

	"google.golang.org/protobuf/types/known/emptypb"

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

func NewServer(
	cmekSvc cmeksvc.CustomerManagedEncryptionKeyService,
	accountCli account.Client,
) globaldedicatedv1.CustomerManagedEncryptionServiceServer {
	return &server{
		svc:        cmekSvc,
		accountCli: accountCli,
	}
}

type server struct {
	svc        cmeksvc.CustomerManagedEncryptionKeyService
	accountCli account.Client
}

func (s server) CreateCustomerManagedEncryptionKey(
	ctx context.Context,
	request *globaldedicatedv1.CreateCustomerManagedEncryptionKeyRequest,
) (*globaldedicatedv1.CustomerManagedEncryptionKey, error) {
	cmek, err := s.svc.Create(ctx, request)
	if err != nil {
		return nil, err
	}
	return cmek, nil
}

func (s server) DeleteCustomerManagedEncryptionKey(
	ctx context.Context,
	request *globaldedicatedv1.DeleteCustomerManagedEncryptionKeyRequest,
) (*emptypb.Empty, error) {
	err := s.svc.Delete(ctx, request)
	if err != nil {
		return nil, err
	}

	return &emptypb.Empty{}, nil
}

func (s server) GetCmekAccessIamPrincipal(
	ctx context.Context,
	request *globaldedicatedv1.GetCmekAccessIamPrincipalRequest,
) (*globaldedicatedv1.GetCmekAccessIamPrincipalResponse, error) {
	iamPrincipal, err := s.svc.GetCmekAccessIamPrincipal(ctx, request)
	if err != nil {
		return nil, err
	}

	resp := &globaldedicatedv1.GetCmekAccessIamPrincipalResponse{}
	switch request.GetCloudProviderId() {
	case globalcommonv1.CloudProvider_AWS:
		resp.Principal = &globaldedicatedv1.GetCmekAccessIamPrincipalResponse_IamPrincipal{
			IamPrincipal: iamPrincipal.AwsPrincipalAccountId,
		}
	case globalcommonv1.CloudProvider_AZURE:
		resp.Principal = &globaldedicatedv1.GetCmekAccessIamPrincipalResponse_AzureCmekPrincipal{
			AzureCmekPrincipal: &globaldedicatedv1.AzureCmekPrincipal{
				AzureAppRegistration: &globaldedicatedv1.AzureAppRegistration{
					AppRegistrationId:   iamPrincipal.AzureAppRegistration.AppRegistrationId,
					AppRegistrationName: iamPrincipal.AzureAppRegistration.AppRegistrationName,
					AppRegistrationUmi:  iamPrincipal.AzureAppRegistration.AppRegistrationUmi,
				},
				AzureKeyVaultKeySuffix: iamPrincipal.AzureCmekKeySuffix,
			},
		}
	default:
		return nil, bizerr.New(bizerr.ErrCodeParams, "cloud provider not support")
	}
	return resp, nil
}

func (s server) GetCustomerManagedEncryptionKey(
	ctx context.Context,
	request *globaldedicatedv1.GetCustomerManagedEncryptionKeyRequest,
) (*globaldedicatedv1.CustomerManagedEncryptionKey, error) {
	cmekEntity, err := s.svc.Get(ctx, request)
	if err != nil {
		return nil, err
	}

	return cmekEntity, nil
}

func (s server) ListCustomerManagedEncryptionKeys(
	ctx context.Context,
	request *globaldedicatedv1.ListCustomerManagedEncryptionKeysRequest,
) (*globaldedicatedv1.ListCustomerManagedEncryptionKeysResponse, error) {
	// TODO support page by @shirui

	cmekEntities, err := s.svc.List(ctx, request)
	if err != nil {
		return nil, err
	}

	return &globaldedicatedv1.ListCustomerManagedEncryptionKeysResponse{
		CustomerManagedEncryptionKeys: cmekEntities,
		Total:                         uint32(len(cmekEntities)),
	}, nil
}
