package secretsource

import (
	"context"
	"fmt"

	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	kms "github.com/alibabacloud-go/kms-20160120/v3/client"
	credential "github.com/aliyun/credentials-go/credentials"

	"github.com/tidbcloud/devops/pkg/infra/config"
	aliyunutil "github.com/tidbcloud/devops/pkg/infra/utils/aliyun"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
)

type sourceAliyunKMS struct {
	client *kms.Client
}

func NewSourceAliyunKMS(conf config.SecretSourceAliyunKMS) (SecretSource, error) {
	baseCred, err := credential.NewCredential(nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create base aliyun credential: %w", err)
	}

	var finalCred = baseCred

	if conf.AssumeRoleARN != "" {
		assumeProvider, err := aliyunutil.NewAssumeRoleProvider(
			baseCred,
			conf.Region,
			conf.AssumeRoleARN,
		)
		if err != nil {
			return nil, fmt.Errorf("failed to init assume role provider: %w", err)
		}

		finalCred = assumeProvider
	}

	aliConfig := &openapi.Config{
		Credential: finalCred,
		RegionId:   pointer.Pointer(conf.Region),
	}

	client, err := kms.NewClient(aliConfig)
	if err != nil {
		return nil, fmt.Errorf("failed to create kms client: %w", err)
	}

	return &sourceAliyunKMS{
		client: client,
	}, nil
}

func (s *sourceAliyunKMS) GetSecretValue(ctx context.Context, name string) (string, error) {
	request := &kms.GetSecretValueRequest{
		SecretName: &name,
	}
	response, err := s.client.GetSecretValue(request)
	if err != nil {
		return "", fmt.Errorf("failed to get secret from aliyun kms: %w", err)
	}
	if response.Body.SecretData == nil {
		return "", fmt.Errorf("secret data is empty")
	}

	return *response.Body.SecretData, nil
}
