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());
    });
};
import { isRetriable } from "../error";
import { getLogger, LOGGER_LEVEL_ENV, newLogger, withLogger } from "../logger";
import { getServiceTrn, Deserialize } from "../message";
import { Publisher, RESERVED_ARNS } from "../sns";
import { Handler, NewHandleResult } from "../sqs";
import { getTracing, lambdaSqsTracing } from "../tracing";
import { LambdaHandler } from "./runtime";
export class LambdaSqsHandler extends 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 && 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 = Deserialize(record.body);
            if (messageInputData instanceof Error) {
                getLogger(ctx).withError(messageInputData)
                    .with({ "message-id": record.messageId })
                    .error("failed to deserialize message");
                return NewHandleResult(record.receiptHandle, undefined, messageInputData);
            }
            let ctxx = lambdaSqsTracing(ctx, record);
            const log = newLogger({
                service: this.serviceName,
                level: process.env[LOGGER_LEVEL_ENV],
                tracingId: getTracing(ctxx),
            });
            ctxx = 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 Publisher({
            region: this.region,
            serviceTrn: getServiceTrn(this.mainCtx),
            // TODO: Verify why if Maya has not the permission to push on a SNS topic it gives NO errors 
            arns: {
                [RESERVED_ARNS.INGRESS_ARN]: process.env.PUBLISHER_ARN
            },
        });
        config.postHooks.push(publisher.defaultHandlerPosthook(this.mainCtx, RESERVED_ARNS.INGRESS_ARN));
        this.handler = new Handler(config);
    }
}
//# sourceMappingURL=sqs-runtime.js.map