"use strict";
/*
Copyright 2019 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bluebird_1 = __importDefault(require("bluebird"));
const logging_1 = require("../logging");
const Queue_1 = require("../util/Queue");
const log = (0, logging_1.getLogger)("scheduler");
// Maps domain => Queue
const queues = {};
function getQueue(server) {
    let q = queues[server.domain];
    if (!q) {
        q = new Queue_1.Queue((item) => {
            return bluebird_1.default.delay(item.addedDelayMs).then(item.fn);
        }, server.getReconnectIntervalMs());
        queues[server.domain] = q;
    }
    return q;
}
/**
 * An IRC connection scheduler. Enables ConnectionInstance to reconnect
 * in a way that queues reconnection requests and services the FIFO queue at a
 * rate determined by ircServer.getReconnectIntervalMs().
 */
exports.default = {
    // Returns a promise that will be resolved when retryConnection returns a promise that
    //  resolves, in other words, when the connection is made. The promise will reject if the
    //  promise returned from retryConnection is rejected.
    // eslint-disable-next-line require-yield
    reschedule: bluebird_1.default.coroutine(function* (server, addedDelayMs, retryConnection, nick) {
        const q = getQueue(server);
        const promise = q.enqueue(`Scheduler.reschedule ${server.domain} ${nick}`, {
            fn: retryConnection,
            addedDelayMs: addedDelayMs
        });
        log.debug(`Queued scheduled promise for ${server.domain} ${nick}` +
            (addedDelayMs > 0 ? ` with ${Math.round(addedDelayMs)}ms added delay` : ''));
        log.debug(`Queue for ${server.domain} length = ${q.size()}`);
        return promise;
    }),
    // Reject all queued promises
    killAll: function () {
        const queueKeys = Object.keys(queues);
        for (let i = 0; i < queueKeys.length; i++) {
            const q = queues[queueKeys[i]];
            q.killAll();
        }
    }
};
//# sourceMappingURL=Scheduler.js.map