"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 SNS_EVENT_SOURCE = 'aws:sns';
const MIN_WAIT_TIME_IN_MS = 0; // No wait time
const MAX_WAIT_TIME_IN_MS = 5 * 60 * 1000; // 5 minutes
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const waitRandomTime = () => {
    const waitTime = Math.floor(Math.random() * (MAX_WAIT_TIME_IN_MS - MIN_WAIT_TIME_IN_MS + 1) + MIN_WAIT_TIME_IN_MS);
    console.log(`Waiting for ${waitTime} ms`);
    return delay(waitTime);
};
const getLayerConfig = (event) => {
    var _a, _b, _c, _d;
    // Check layerArn in the event
    const { Sns } = event.Records.find((record) => record.EventSource === SNS_EVENT_SOURCE);
    if (!Sns) {
        throw new Error('No SNS notification found in the event');
    }
    const layerArn = (_b = (_a = Sns === null || Sns === void 0 ? void 0 : Sns.MessageAttributes) === null || _a === void 0 ? void 0 : _a.LayerArn) === null || _b === void 0 ? void 0 : _b.Value;
    const region = (_d = (_c = Sns === null || Sns === void 0 ? void 0 : Sns.MessageAttributes) === null || _c === void 0 ? void 0 : _c.Region) === null || _d === void 0 ? void 0 : _d.Value;
    return {
        layerArn,
        region,
    };
};
const updateFunction = (layerArn) => __awaiter(void 0, void 0, void 0, function* () {
    const client = new client_lambda_1.LambdaClient({ region: process.env.AWS_REGION });
    const lambdaFunctionArn = process.env.LAMBDA_FUNCTION_ARN;
    const command = new client_lambda_1.UpdateFunctionConfigurationCommand({
        FunctionName: lambdaFunctionArn,
        Layers: [layerArn],
    });
    const response = yield client.send(command);
    return response;
});
const handler = (event) => __awaiter(void 0, void 0, void 0, function* () {
    // Record the received event in logs
    console.log('Received event', JSON.stringify(event, null, 4));
    const { layerArn, region } = getLayerConfig(event);
    if (!layerArn || !region) {
        throw new Error('Layer ARN or region is missing in the notification event');
    }
    if (region !== process.env.AWS_REGION) {
        console.log(`Region ${region} in notification is not same as the current region ${process.env.AWS_REGION}. Skipping update.`);
        return;
    }
    // Wait for a random time up to 5 minutes.
    // This is to avoid all the functions updating at the same time which may result in throttling errors.
    yield waitRandomTime();
    // Update the function configuration with the new layer version
    try {
        const response = yield updateFunction(layerArn);
        console.log(`Updated layer version to ${layerArn}`, response);
    }
    catch (e) {
        console.error('Error Updating layer', e);
        throw e;
    }
});
exports.handler = handler;
