package remoteencryptor

import (
	"context"

	"github.com/tidbcloud/pkgv2/secret/encrypt"
	secretprovider "github.com/tidbcloud/pkgv2/secret/provider"
	"go.opentelemetry.io/otel"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/remoteencryptor"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/pkg/config"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

var tracer = otel.Tracer("remoteencryptor")

type clientImp struct {
	enc encrypt.Encryptor
}

func NewEncryptor(cfg *config.Config) remoteencryptor.Client {
	cmkArn := cfg.AwsConfig.CMKArn
	enc, err := secretprovider.NewSecretEncryptor(cmkArn)
	if err != nil {
		panic("initialize encryptor failed")
	}
	return &clientImp{
		enc: enc,
	}
}

func (e clientImp) EncryptBase64(ctx context.Context, text string) (string, bizerr.BizError) {
	_, span := tracer.Start(ctx, "Encryptor.EncryptBase64")
	defer span.End()

	secretTxt, err := encrypt.EncryptBase64(e.enc, encrypt.Secret(text))
	if err != nil {
		return "", bizerr.WrapError(err, "encrypt failed")
	}
	return secretTxt, nil
}

func (e clientImp) DecryptBase64(ctx context.Context, encryptedEncoded string) (string, bizerr.BizError) {
	_, span := tracer.Start(ctx, "Encryptor.DecryptBase64")
	defer span.End()

	plainText, err := encrypt.DecryptBase64(e.enc, encryptedEncoded)
	if err != nil {
		return "", bizerr.WrapError(err, "decrypt failed")
	}
	return string(plainText), nil
}
