import { readEnvString } from '../../../common/ExternalServiceUtils.js';
import { AwsSigV4 } from '../../../common/index.js';
import { ErrorFactory } from '../../../exceptions/ZintrustError.js';
const sha256Hex = (data) => AwsSigV4.sha256Hex(data);
const buildAuthorization = (params) => {
    const canonicalUri = '/';
    const canonicalQueryString = '';
    const headers = {
        'content-type': 'application/x-amz-json-1.1',
        host: params.host,
        'x-amz-date': params.amzDate,
        'x-amz-target': params.target,
    };
    const sessionToken = params.credentials.sessionToken;
    if (typeof sessionToken === 'string' && sessionToken.trim() !== '') {
        headers['x-amz-security-token'] = sessionToken;
    }
    const payloadHash = sha256Hex(params.body);
    return AwsSigV4.buildAuthorization({
        method: params.method,
        canonicalUri,
        canonicalQueryString,
        headers,
        payloadHash,
        region: params.region,
        service: 'secretsmanager',
        amzDate: params.amzDate,
        dateStamp: params.dateStamp,
        credentials: params.credentials,
    });
};
const parseMaybeJson = (value) => {
    try {
        return JSON.parse(value);
    }
    catch {
        return value;
    }
};
const requestAwsSecretsManager = async (region, credentials, target, body) => {
    const host = `secretsmanager.${region}.amazonaws.com`;
    const url = `https://${host}/`;
    const now = new Date();
    const { amzDate, dateStamp } = AwsSigV4.toAmzDate(now);
    const bodyJson = JSON.stringify(body);
    const { authorization } = buildAuthorization({
        method: 'POST',
        host,
        region,
        amzDate,
        dateStamp,
        credentials,
        target,
        body: bodyJson,
    });
    const headers = {
        'content-type': 'application/x-amz-json-1.1',
        'x-amz-date': amzDate,
        'x-amz-target': target,
        Authorization: authorization,
    };
    const sessionToken = credentials.sessionToken;
    if (typeof sessionToken === 'string' && sessionToken.trim() !== '') {
        headers['x-amz-security-token'] = sessionToken;
    }
    const res = await fetch(url, {
        method: 'POST',
        headers,
        body: bodyJson,
    });
    const text = await res.text();
    if (!res.ok) {
        throw ErrorFactory.createCliError(`AWS SecretsManager request failed (${res.status})`, {
            status: res.status,
            body: text,
        });
    }
    return JSON.parse(text);
};
export const AwsSecretsManager = Object.freeze({
    createFromEnv() {
        const region = readEnvString('AWS_REGION') || readEnvString('AWS_DEFAULT_REGION');
        const accessKeyId = readEnvString('AWS_ACCESS_KEY_ID');
        const secretAccessKey = readEnvString('AWS_SECRET_ACCESS_KEY');
        const sessionToken = readEnvString('AWS_SESSION_TOKEN') || undefined;
        if (region.trim() === '' || accessKeyId.trim() === '' || secretAccessKey.trim() === '') {
            throw ErrorFactory.createCliError('AWS credentials missing: set AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY');
        }
        const credentials = { accessKeyId, secretAccessKey, sessionToken };
        const getValue = async (secretId, jsonKey) => {
            const data = await requestAwsSecretsManager(region, credentials, 'secretsmanager.GetSecretValue', {
                SecretId: secretId,
            });
            if (typeof data.SecretString !== 'string')
                return null;
            if (jsonKey === undefined)
                return data.SecretString;
            const parsed = parseMaybeJson(data.SecretString);
            if (typeof parsed === 'object' && parsed !== null) {
                const obj = parsed;
                if (!(jsonKey in obj))
                    return null;
                const v = obj[jsonKey];
                if (typeof v === 'string')
                    return v;
                return JSON.stringify(v);
            }
            return null;
        };
        const putValue = async (secretId, value) => {
            await requestAwsSecretsManager(region, credentials, 'secretsmanager.PutSecretValue', {
                SecretId: secretId,
                SecretString: value,
            });
        };
        return { getValue, putValue };
    },
    doctorEnv() {
        const missing = [];
        const awsRegion = readEnvString('AWS_REGION').trim();
        const awsDefaultRegion = readEnvString('AWS_DEFAULT_REGION').trim();
        if (awsRegion === '' && awsDefaultRegion === '') {
            missing.push('AWS_REGION');
        }
        const accessKeyId = readEnvString('AWS_ACCESS_KEY_ID').trim();
        if (accessKeyId === '')
            missing.push('AWS_ACCESS_KEY_ID');
        const secretAccessKey = readEnvString('AWS_SECRET_ACCESS_KEY').trim();
        if (secretAccessKey === '')
            missing.push('AWS_SECRET_ACCESS_KEY');
        return missing;
    },
});
export default AwsSecretsManager;
