"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Subscriber = void 0;
const tsyringe_1 = require("tsyringe");
const NetworkNodeFacade_1 = require("../NetworkNodeFacade");
const LoggerFactory_1 = require("../utils/LoggerFactory");
const MessagePipelineFactory_1 = require("./MessagePipelineFactory");
const SubscriptionSession_1 = require("./SubscriptionSession");
let Subscriber = class Subscriber {
    subSessions = new Map();
    node;
    messagePipelineFactory;
    logger;
    constructor(node, messagePipelineFactory, loggerFactory) {
        this.node = node;
        this.messagePipelineFactory = messagePipelineFactory;
        this.logger = loggerFactory.createLogger(module);
    }
    getOrCreateSubscriptionSession(streamPartId) {
        if (this.subSessions.has(streamPartId)) {
            return this.getSubscriptionSession(streamPartId);
        }
        const subSession = new SubscriptionSession_1.SubscriptionSession(streamPartId, this.messagePipelineFactory, this.node);
        this.subSessions.set(streamPartId, subSession);
        subSession.onRetired.listen(() => {
            this.subSessions.delete(streamPartId);
        });
        this.logger.debug('Created new SubscriptionSession', { streamPartId });
        return subSession;
    }
    async add(sub) {
        const subSession = this.getOrCreateSubscriptionSession(sub.streamPartId);
        // add subscription to subSession
        try {
            await subSession.add(sub);
        }
        catch (err) {
            this.logger.debug('Failed to add Subscription to SubscriptionSession', err);
            // clean up if fail
            await this.remove(sub);
            throw err;
        }
    }
    async remove(sub) {
        const subSession = this.subSessions.get(sub.streamPartId);
        if (!subSession) {
            return;
        }
        await subSession.remove(sub);
    }
    getSubscriptions() {
        return [...this.subSessions.values()].reduce((o, s) => {
            // @ts-expect-error private
            o.push(...s.subscriptions);
            return o;
        }, []);
    }
    /**
     * Get subscription session for matching sub options.
     */
    getSubscriptionSession(streamPartId) {
        return this.subSessions.get(streamPartId);
    }
    countSubscriptionSessions() {
        return this.subSessions.size;
    }
};
exports.Subscriber = Subscriber;
exports.Subscriber = Subscriber = __decorate([
    (0, tsyringe_1.scoped)(tsyringe_1.Lifecycle.ContainerScoped),
    __metadata("design:paramtypes", [NetworkNodeFacade_1.NetworkNodeFacade,
        MessagePipelineFactory_1.MessagePipelineFactory,
        LoggerFactory_1.LoggerFactory])
], Subscriber);
//# sourceMappingURL=Subscriber.js.map