"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.LambdaSqsHandler = void 0;
const error_1 = require("../error");
const logger_1 = require("../logger");
const message_1 = require("../message");
const sns_1 = require("../sns");
const sqs_1 = require("../sqs");
const tracing_1 = require("../tracing");
const runtime_1 = require("./runtime");
class LambdaSqsHandler extends runtime_1.LambdaHandler {
    constructor(region, serviceName, config) {
        super(region, serviceName);
        this.mainLoop = () => {
            return (event, context) => __awaiter(this, void 0, void 0, function* () {
                this.setTimeout(this.mainCtx, context.getRemainingTimeInMillis());
                Error.stackTraceLimit = 50;
                if (!Object.keys(event).includes("Records")) {
                    return undefined;
                }
                const ret = {
                    batchItemFailures: new Array(),
                };
                for (const evnt of event.Records) {
                    const result = yield this.processMessage(this.mainCtx, evnt, context);
                    if (result.error && (0, error_1.isRetriable)(result.error)) {
                        ret.batchItemFailures.push({ itemIdentifier: result.messageReceipt });
                        continue;
                    }
                }
                this.clearTimeout();
                return ret;
            });
        };
        this.processMessage = (ctx, record, context) => __awaiter(this, void 0, void 0, function* () {
            const messageInputData = (0, message_1.Deserialize)(record.body);
            if (messageInputData instanceof Error) {
                (0, logger_1.getLogger)(ctx).withError(messageInputData)
                    .with({ "message-id": record.messageId })
                    .error("failed to deserialize message");
                return (0, sqs_1.NewHandleResult)(record.receiptHandle, undefined, messageInputData);
            }
            let ctxx = (0, tracing_1.lambdaSqsTracing)(ctx, record);
            const log = (0, logger_1.newLogger)({
                service: this.serviceName,
                level: process.env[logger_1.LOGGER_LEVEL_ENV],
                tracingId: (0, tracing_1.getTracing)(ctxx),
            });
            ctxx = (0, logger_1.withLogger)(ctxx, log);
            this.setTimeout(ctxx, context.getRemainingTimeInMillis());
            log.info("handling event");
            log.with({
                "eventMessage": messageInputData
            }).debug("message data");
            return yield this.handler.handle(ctxx, record.receiptHandle, messageInputData);
        });
        const publisher = new sns_1.Publisher({
            region: this.region,
            serviceTrn: (0, message_1.getServiceTrn)(this.mainCtx),
            // TODO: Verify why if Maya has not the permission to push on a SNS topic it gives NO errors 
            arns: {
                [sns_1.RESERVED_ARNS.INGRESS_ARN]: process.env.PUBLISHER_ARN
            },
        });
        config.postHooks.push(publisher.defaultHandlerPosthook(this.mainCtx, sns_1.RESERVED_ARNS.INGRESS_ARN));
        this.handler = new sqs_1.Handler(config);
    }
}
exports.LambdaSqsHandler = LambdaSqsHandler;
//# sourceMappingURL=sqs-runtime.js.map