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 { SNSClient, PublishBatchCommand } from "@aws-sdk/client-sns";
import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
import { v4 as uuidv4 } from 'uuid';
import { Serialize } from "../message";
import { RetriableError } from "../error";
import { getTracing, MESSAGE_TRACING_ATTRIBUTE } from "../tracing";
export var RESERVED_ARNS;
(function (RESERVED_ARNS) {
    RESERVED_ARNS["INGRESS_ARN"] = "ingress-arn";
})(RESERVED_ARNS || (RESERVED_ARNS = {}));
export 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 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: uuidv4(),
                    Message: Serialize(message),
                    MessageAttributes: {
                        [MESSAGE_TRACING_ATTRIBUTE]: {
                            StringValue: 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 RetriableError(err);
                }
            });
        };
        this.config = config;
        this.client = new SNSClient({
            credentials: fromNodeProviderChain(),
            region: config.region,
        });
    }
}
//# sourceMappingURL=publisher.js.map