"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.Publisher = exports.RESERVED_ARNS = void 0;
const client_sns_1 = require("@aws-sdk/client-sns");
const credential_providers_1 = require("@aws-sdk/credential-providers");
const uuid_1 = require("uuid");
const message_1 = require("../message");
const error_1 = require("../error");
const tracing_1 = require("../tracing");
var RESERVED_ARNS;
(function (RESERVED_ARNS) {
    RESERVED_ARNS["INGRESS_ARN"] = "ingress-arn";
})(RESERVED_ARNS = exports.RESERVED_ARNS || (exports.RESERVED_ARNS = {}));
class Publisher {
    constructor(config) {
        /**
         * Publish messages to topic
         */
        this.publish = (ctx, topic, ...messages) => __awaiter(this, void 0, void 0, function* () {
            const arn = this.config.arns[topic];
            if (arn == undefined) {
                return Promise.reject(new Error("no arn configured for topic: " + topic));
            }
            const chunkSize = 10;
            for (let i = 0; i < messages.length; i += chunkSize) {
                const chunk = messages.slice(i, i + chunkSize);
                // Set the parameters
                const params = {
                    PublishBatchRequestEntries: yield this.createBatchMessageEntries(ctx, chunk),
                    TopicArn: arn
                };
                try {
                    yield this.client.send(new client_sns_1.PublishBatchCommand(params));
                }
                catch (err) {
                    return Promise.reject(err);
                }
            }
            return undefined;
        });
        this.createBatchMessageEntries = (ctx, messages) => __awaiter(this, void 0, void 0, function* () {
            const entries = [];
            messages.forEach(message => {
                entries.push({
                    Id: (0, uuid_1.v4)(),
                    Message: (0, message_1.Serialize)(message),
                    MessageAttributes: {
                        [tracing_1.MESSAGE_TRACING_ATTRIBUTE]: {
                            StringValue: (0, tracing_1.getTracing)(ctx),
                            DataType: "String",
                        }
                    }
                });
            });
            return entries;
        });
        this.defaultHandlerPosthook = (ctx, topic) => {
            return (ctx, result) => __awaiter(this, void 0, void 0, function* () {
                var _a;
                if (!((_a = result.broadcastMessages) === null || _a === void 0 ? void 0 : _a.length)) {
                    return undefined;
                }
                const err = yield this.publish(ctx, topic, ...result.broadcastMessages);
                if (err != undefined) {
                    return new error_1.RetriableError(err);
                }
            });
        };
        this.config = config;
        this.client = new client_sns_1.SNSClient({
            credentials: (0, credential_providers_1.fromNodeProviderChain)(),
            region: config.region,
        });
    }
}
exports.Publisher = Publisher;
//# sourceMappingURL=publisher.js.map