"use strict";
/*!
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const internal_1 = require("../../internal");
/**
 * @hidden
 */
class EventedConnection extends events_1.EventEmitter {
    constructor() {
        super(...arguments);
        this._quality = new internal_1.ConnectionQuality();
        this._promises = new Map();
        this.statsTracker = new internal_1.NetworkStatsTracker();
        this.queuedMessages = [];
    }
    /** @inheritdoc */
    get quality() { return this._quality; }
    /** @inheritdoc */
    get promises() { return this._promises; }
    /** @inheritdoc */
    get statsReport() {
        return this.statsTracker.reportStats();
    }
    /**
     * @hidden
     * Replace this connection's quality tracker
     */
    linkConnectionQuality(quality) {
        this._quality = quality;
        this.emit('linkQuality', quality);
    }
    // Bug in Node: EventEmitter doesn't alias this method
    /** @inheritdoc */
    off(event, listener) {
        return this.removeListener(event, listener);
    }
    /** @inheritdoc */
    close() {
        this.emit('close');
    }
    /** @inheritdoc */
    send(message, serializedMessage) {
        this.emit('send', message, serializedMessage);
    }
    /** @inheritdoc */
    recv(message, serializedMessage) {
        /* eslint-disable @typescript-eslint/no-use-before-define */
        const hasListeners = () => !!this.listeners('recv').length;
        const checkAndLoop = () => {
            this.timeout = undefined;
            if (hasListeners()) {
                dispatchQueuedMessages();
            }
            else {
                setRetryLoop();
            }
        };
        const dispatchQueuedMessages = () => {
            for (const queuedMessage of this.queuedMessages.splice(0)) {
                this.emit('recv', ...queuedMessage);
            }
        };
        const setRetryLoop = () => this.timeout = this.timeout || setTimeout(checkAndLoop, 100);
        if (hasListeners()) {
            this.emit('recv', message, serializedMessage);
        }
        else {
            this.queuedMessages.push([message, serializedMessage]);
            setRetryLoop();
        }
        /* eslint-enable @typescript-eslint/no-use-before-define */
    }
}
exports.EventedConnection = EventedConnection;
//# sourceMappingURL=eventedConnection.js.map