"use strict";
/*
 * @adonisjs/core
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.HealthCheck = void 0;
/**
 * The module exposes the API to find the health, liveliness and readiness of
 * the system. You can also add your own checkers.
 */
class HealthCheck {
    /**
     * Returns an array of registered services names
     */
    get servicesList() {
        return Object.keys(this.healthCheckers);
    }
    constructor(application) {
        this.application = application;
        /**
         * A copy of registered checkers
         */
        this.healthCheckers = {};
        /**
         * Reference to the IoC container to resolve health checkers
         */
        this.resolver = this.application.container.getResolver('report');
    }
    /**
     * Invokes a given checker to collect the report metrics.
     */
    async invokeChecker(service, reportSheet) {
        const checker = this.healthCheckers[service];
        let report;
        try {
            if (typeof checker === 'function') {
                report = await checker();
            }
            else {
                report = await this.resolver.call(checker);
            }
            report.displayName = report.displayName || service;
        }
        catch (error) {
            report = {
                displayName: service,
                health: { healthy: false, message: error.message },
                meta: { fatal: true },
            };
        }
        reportSheet[service] = report;
        return report.health.healthy;
    }
    /**
     * A boolean to know, if all health checks have passed
     * or not.
     */
    async isLive() {
        if (!this.isReady()) {
            return false;
        }
        const { healthy } = await this.getReport();
        return healthy;
    }
    /**
     * Add a custom checker to check a given service connectivity
     * with the server
     */
    addChecker(service, checker) {
        this.healthCheckers[service] = checker;
    }
    /**
     * Ensure that application is ready. This relies on the application module.
     */
    isReady() {
        return this.application.isReady;
    }
    /**
     * Returns the health check reports. The health checks are performed when
     * this method is invoked.
     */
    async getReport() {
        const report = {};
        await Promise.all(Object.keys(this.healthCheckers).map((service) => {
            return this.invokeChecker(service, report);
        }));
        /**
         * Finding unhealthy service to know if system is healthy or not
         */
        const unhealthyService = Object.keys(report).find((service) => !report[service].health.healthy);
        return { healthy: !unhealthyService, report };
    }
}
exports.HealthCheck = HealthCheck;
