"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("@deepstream/types");
const events_1 = require("events");
class DependencyInitialiser {
    /**
     * This class is used to track the initialization of an individual service or plugin
     */
    constructor(config, services, dependency, name) {
        this.config = config;
        this.services = services;
        this.dependency = dependency;
        this.name = name;
        this.isReady = false;
        this.timeout = null;
        this.emitter = new events_1.EventEmitter();
        if (typeof this.dependency.whenReady !== 'function') {
            const errorMessage = `${this.name} needs to implement async whenReady and close, please look at the DeepstreamPlugin API here`; // TODO: Insert link
            this.services.logger.fatal(types_1.EVENT.PLUGIN_INITIALIZATION_ERROR, errorMessage);
            this.services.notifyFatalException();
            return;
        }
        this.timeout = setTimeout(this.onTimeout.bind(this), this.config.dependencyInitializationTimeout);
        if (this.dependency.init) {
            this.dependency.init();
        }
        this.dependency
            .whenReady()
            .then(this.onReady.bind(this));
    }
    async whenReady() {
        if (!this.isReady) {
            return new Promise((resolve) => this.emitter.once('ready', resolve));
        }
    }
    /**
     * Returns the underlying dependency (e.g. the Logger, StorageConnector etc.)
     */
    getDependency() {
        return this.dependency;
    }
    /**
     * Callback for succesfully initialised dependencies
     */
    onReady() {
        if (this.timeout) {
            clearTimeout(this.timeout);
        }
        this.dependency.description = this.dependency.description || this.dependency.type;
        const dependencyType = this.dependency.description ? `: ${this.dependency.description}` : ': no dependency description provided';
        this.services.logger.info(types_1.EVENT.INFO, `${this.name} ready${dependencyType}`);
        this.isReady = true;
        this.emitter.emit('ready');
    }
    /**
     * Callback for dependencies that weren't initialised in time
     */
    onTimeout() {
        const message = `${this.name} wasn't initialised in time`;
        if (this.name === 'logger') {
            console.error('Error while initialising log dependency dependency');
            console.error(message);
            this.services.notifyFatalException();
        }
        this.services.logger.fatal(types_1.EVENT.PLUGIN_INITIALIZATION_TIMEOUT, message);
    }
}
exports.DependencyInitialiser = DependencyInitialiser;
//# sourceMappingURL=dependency-initialiser.js.map