// Package secrets fetches runtime secrets from AWS Secrets Manager.
// Values are resolved once at sentry boot and cached in memory.
package secrets

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
)

// Manager wraps a Secrets Manager client.
type Manager struct {
	client *secretsmanager.Client
}

// New constructs a Manager from an already-configured client.
// Callers build the client via aws-sdk-go-v2/config.LoadDefaultConfig
// so IAM task roles, region, and credentials providers all work without
// further plumbing.
func New(client *secretsmanager.Client) *Manager {
	return &Manager{client: client}
}

// GetString returns the secret string value for the given ARN or name.
func (m *Manager) GetString(ctx context.Context, arn string) (string, error) {
	out, err := m.client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{
		SecretId: aws.String(arn),
	})
	if err != nil {
		return "", fmt.Errorf("secrets: get %s: %w", arn, err)
	}
	if out.SecretString == nil {
		return "", fmt.Errorf("secrets: %s has no string value", arn)
	}
	return *out.SecretString, nil
}

// GetJSON fetches the secret string and unmarshals it into target.
func (m *Manager) GetJSON(ctx context.Context, arn string, target any) error {
	s, err := m.GetString(ctx, arn)
	if err != nil {
		return err
	}
	if err := json.Unmarshal([]byte(s), target); err != nil {
		return fmt.Errorf("secrets: unmarshal %s: %w", arn, err)
	}
	return nil
}
