"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.S3CSVClient = void 0;
const client_sts_1 = require("@aws-sdk/client-sts");
const client_s3_1 = require("@aws-sdk/client-s3");
const uuid_1 = require("@lukeed/uuid");
const process = __importStar(require("process"));
const actions_core_1 = require("@segment/actions-core");
class S3CSVClient {
    constructor(region, roleArn, externalId) {
        this.region = region;
        this.roleSessionName = (0, uuid_1.v4)();
        this.roleArn = roleArn;
        this.externalId = externalId;
    }
    async assumeRole() {
        const intermediaryARN = process.env.AMAZON_S3_ACTIONS_ROLE_ADDRESS;
        const intermediaryExternalId = process.env.AMAZON_S3_ACTIONS_EXTERNAL_ID;
        const intermediaryCreds = await this.getSTSCredentials(intermediaryARN, intermediaryExternalId);
        return this.getSTSCredentials(this.roleArn, this.externalId, intermediaryCreds);
    }
    async getSTSCredentials(roleId, externalId, credentials) {
        const options = { region: this.region, credentials };
        const stsClient = new client_sts_1.STSClient(options);
        const command = new client_sts_1.AssumeRoleCommand({
            RoleArn: roleId,
            RoleSessionName: this.roleSessionName,
            ExternalId: externalId
        });
        const result = await stsClient.send(command);
        if (!result.Credentials ||
            !result.Credentials.AccessKeyId ||
            !result.Credentials.SecretAccessKey ||
            !result.Credentials.SessionToken) {
            throw new actions_core_1.IntegrationError('Failed to assume role', actions_core_1.ErrorCodes.INVALID_AUTHENTICATION, 403);
        }
        return {
            accessKeyId: result.Credentials.AccessKeyId,
            secretAccessKey: result.Credentials.SecretAccessKey,
            sessionToken: result.Credentials.SessionToken
        };
    }
    async uploadS3(settings, audienceSettings, fileContent, audienceName) {
        let filename = audienceSettings.filename ?? '';
        const dateSuffix = new Date().toISOString().replace(/[:.]/g, '-');
        if (filename.endsWith('.csv')) {
            filename = filename.replace('.csv', `_${dateSuffix}.csv`);
        }
        else {
            audienceName = audienceName ? audienceName.toLowerCase() : '';
            filename = filename ? `${filename}_${audienceName}_${dateSuffix}.csv` : `${audienceName}_${dateSuffix}.csv`;
        }
        const bucketName = settings.s3_aws_bucket_name;
        const folderName = ['', null, undefined].includes(audienceSettings?.s3_aws_folder_name)
            ? ''
            : audienceSettings?.s3_aws_folder_name?.endsWith('/')
                ? audienceSettings?.s3_aws_folder_name
                : `${audienceSettings?.s3_aws_folder_name}/`;
        const credentials = await this.assumeRole();
        const s3Client = new client_s3_1.S3Client({
            region: this.region,
            credentials: {
                accessKeyId: credentials.accessKeyId,
                secretAccessKey: credentials.secretAccessKey,
                sessionToken: credentials.sessionToken
            }
        });
        const objectKey = folderName ? `${folderName}${filename}` : filename;
        const uploadParams = {
            Bucket: bucketName,
            Key: objectKey,
            Body: fileContent,
            ContentType: 'text/csv'
        };
        try {
            await s3Client.send(new client_s3_1.PutObjectCommand(uploadParams));
            return { statusCode: 200, message: 'Upload successful' };
        }
        catch (err) {
            throw new Error(`Non-retryable error: ${err}`);
        }
    }
}
exports.S3CSVClient = S3CSVClient;
//# sourceMappingURL=s3.js.map