"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _ChannelSpecificEventBuffer_subject, _ChannelSpecificEventBuffer_buffer, _ChannelEventBuffer_buffers;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientEventInterface = void 0;
const rxjs_1 = require("rxjs");
class ChannelSpecificEventBuffer {
    constructor() {
        _ChannelSpecificEventBuffer_subject.set(this, null);
        _ChannelSpecificEventBuffer_buffer.set(this, []);
    }
    next(item) {
        if (!__classPrivateFieldGet(this, _ChannelSpecificEventBuffer_subject, "f")) {
            __classPrivateFieldGet(this, _ChannelSpecificEventBuffer_buffer, "f").push(item);
        }
        else {
            __classPrivateFieldGet(this, _ChannelSpecificEventBuffer_subject, "f").next(item);
        }
    }
    flush() {
        if (!__classPrivateFieldGet(this, _ChannelSpecificEventBuffer_subject, "f")) {
            __classPrivateFieldSet(this, _ChannelSpecificEventBuffer_subject, new rxjs_1.Subject(), "f");
        }
        try {
            return [__classPrivateFieldGet(this, _ChannelSpecificEventBuffer_buffer, "f"), __classPrivateFieldGet(this, _ChannelSpecificEventBuffer_subject, "f").asObservable()];
        }
        finally {
            __classPrivateFieldSet(this, _ChannelSpecificEventBuffer_buffer, [], "f");
        }
    }
    complete() {
        var _a;
        (_a = __classPrivateFieldGet(this, _ChannelSpecificEventBuffer_subject, "f")) === null || _a === void 0 ? void 0 : _a.complete();
    }
}
_ChannelSpecificEventBuffer_subject = new WeakMap(), _ChannelSpecificEventBuffer_buffer = new WeakMap();
class ChannelEventBuffer {
    constructor() {
        _ChannelEventBuffer_buffers.set(this, new Map());
    }
    getBuffer(channel) {
        let buffer = __classPrivateFieldGet(this, _ChannelEventBuffer_buffers, "f").get(channel);
        if (!buffer) {
            buffer = new ChannelSpecificEventBuffer();
            __classPrivateFieldGet(this, _ChannelEventBuffer_buffers, "f").set(channel, buffer);
        }
        return buffer;
    }
    next(channel, item) {
        let buffer = this.getBuffer(channel);
        buffer.next(item);
    }
    subscribe(channel) {
        let buffer = this.getBuffer(channel);
        return new rxjs_1.Observable(subscriber => {
            const [data, subject] = buffer.flush();
            const subscription = subject.pipe((0, rxjs_1.startWith)(...data)).subscribe(subscriber);
            return () => {
                subscription.unsubscribe();
            };
        }).pipe((0, rxjs_1.share)());
    }
    closeChannel(channel) {
        __classPrivateFieldGet(this, _ChannelEventBuffer_buffers, "f").delete(channel);
    }
    complete() {
        for (const buffer of __classPrivateFieldGet(this, _ChannelEventBuffer_buffers, "f").values()) {
            buffer.complete();
        }
    }
}
_ChannelEventBuffer_buffers = new WeakMap();
class ClientEventInterface {
    constructor() {
        this.data$ = new ChannelEventBuffer();
        this.extendedData$ = new ChannelEventBuffer();
        this.eof$ = new ChannelEventBuffer();
        this.close$ = new ChannelEventBuffer();
        this.disconnect$ = new rxjs_1.Subject();
        this.x11ChannelOpen$ = new rxjs_1.Subject();
        this.tcpChannelOpen$ = new rxjs_1.Subject();
        this.agentChannelOpen$ = new rxjs_1.Subject();
        this.banner$ = new rxjs_1.AsyncSubject();
        this.dataCallback = (_, channel, data) => {
            this.data$.next(channel, data);
        };
        this.extendedDataCallback = (_, channel, ext, data) => {
            this.extendedData$.next(channel, [ext, data]);
        };
        this.eofCallback = (_, channel) => {
            this.eof$.next(channel);
        };
        this.closeCallback = (_, channel) => {
            this.close$.next(channel);
            this.data$.closeChannel(channel);
            this.extendedData$.closeChannel(channel);
            this.eof$.closeChannel(channel);
            this.close$.closeChannel(channel);
        };
        this.disconnectCallback = () => {
            this.disconnect$.next();
        };
        this.x11ChannelOpenCallback = (_, channel, address, port) => {
            this.x11ChannelOpen$.next([channel, address, port]);
        };
        this.tcpChannelOpenCallback = (_, channel, connectedAddress, connectedPort, originatorAddress, originatorPort) => {
            this.tcpChannelOpen$.next([channel, connectedAddress, connectedPort, originatorAddress, originatorPort]);
        };
        this.agentChannelOpenCallback = (_, channel) => {
            this.agentChannelOpen$.next([channel]);
        };
        this.bannerCallback = (_, banner) => {
            this.banner$.next(banner);
            this.banner$.complete();
        };
    }
    complete() {
        this.data$.complete();
        this.extendedData$.complete();
        this.eof$.complete();
        this.close$.complete();
        this.disconnect$.complete();
        this.x11ChannelOpen$.complete();
        this.tcpChannelOpen$.complete();
        this.agentChannelOpen$.complete();
        this.banner$.complete();
    }
}
exports.ClientEventInterface = ClientEventInterface;
