"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;
const client_lambda_1 = require("@aws-sdk/client-lambda");
const client_sns_1 = require("@aws-sdk/client-sns");
const MAX_ITEMS = 50;
const { LAYER_NAME, SNS_TOPIC_ARN, SNS_TOPIC_REGION } = process.env;
/*
 * NOTE: The list of supported regions must be kept in sync amongst all of:
 * - packages/amplify-graphql-model-transformer/publish-notification-lambda/src/index.ts
 * - the internal pipeline that actually publishes new layer versions
 */
const SUPPORTED_REGIONS = [
    'ap-northeast-1',
    'ap-northeast-2',
    'ap-northeast-3',
    'ap-south-1',
    'ap-southeast-1',
    'ap-southeast-2',
    'ca-central-1',
    'eu-central-1',
    'eu-north-1',
    'eu-west-1',
    'eu-west-2',
    'eu-west-3',
    'me-south-1',
    'sa-east-1',
    'us-east-1',
    'us-east-2',
    'us-west-1',
    'us-west-2',
];
const getLatestVersion = (layerName, region) => __awaiter(void 0, void 0, void 0, function* () {
    const client = new client_lambda_1.LambdaClient({ region });
    const versions = [];
    let nextMarker;
    do {
        const command = new client_lambda_1.ListLayerVersionsCommand({
            LayerName: layerName,
            MaxItems: MAX_ITEMS,
            Marker: nextMarker,
        });
        // eslint-disable-next-line no-await-in-loop
        const response = yield client.send(command);
        if (response.LayerVersions) {
            versions.push(...response.LayerVersions);
        }
        nextMarker = response === null || response === void 0 ? void 0 : response.NextMarker;
    } while (nextMarker);
    const result = versions.sort((a, b) => b.Version - a.Version)[0];
    return {
        layerArn: result.LayerVersionArn,
        region,
    };
});
const getLatestVersions = () => __awaiter(void 0, void 0, void 0, function* () {
    const promises = SUPPORTED_REGIONS.map((region) => getLatestVersion(LAYER_NAME, region));
    return Promise.all(promises);
});
const publishMessage = (layerArn, region) => __awaiter(void 0, void 0, void 0, function* () {
    if (!layerArn || !region) {
        console.log(`Layer ARN or region is missing - skipping notification for layer ${layerArn} in region ${region}`);
        return;
    }
    const client = new client_sns_1.SNSClient({ region: SNS_TOPIC_REGION });
    const command = new client_sns_1.PublishCommand({
        TopicArn: SNS_TOPIC_ARN,
        Message: 'New Lambda Layer version is available',
        Subject: 'New Lambda Layer version is available',
        MessageAttributes: {
            LayerArn: {
                DataType: 'String',
                StringValue: layerArn,
            },
            Region: {
                DataType: 'String',
                StringValue: region,
            },
        },
    });
    yield client.send(command);
});
const publishNotification = () => __awaiter(void 0, void 0, void 0, function* () {
    const layers = yield getLatestVersions();
    const promises = [];
    layers.forEach((layer) => {
        if (!layer.layerArn || !layer.region) {
            console.log('Layer Arn or region is missing in the notification event', layer);
            return;
        }
        promises.push(publishMessage(layer.layerArn, layer.region));
        console.log(`Published notification for layer ${layer.layerArn} in region ${layer.region}`);
    });
    yield Promise.all(promises);
});
const handler = () => __awaiter(void 0, void 0, void 0, function* () {
    yield publishNotification();
});
exports.handler = handler;
