Source: reporter/reporter.js

import { Logger } from './logger.js';

/**
 * Report data back to the home base.
 */

class Reporter {

    constructor() {

        /**
         * @protected
         * @type {Object<SyslogLevel,Array<function>>}
         */

        this._actions = {}
        

        /**
         * @protected
         * @type {Array<Logger>}
         */

        this._loggers = [];

        this._rebuildActionDictionary();
    }


    /** @type {Array<SyslogLevel>} */

    static logLevels = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'];


    /** @type {Object<SyslogLevel,SyslogLevelNum>} */

    static syslogLevelsIndexed = {
        'emergency': 0,
        'alert': 1,
        'critical': 2,
        'error': 3,
        'warning': 4,
        'notice': 5,
        'info': 6,
        'debug': 8
    };


    /**
     * @protected
     */

    _rebuildActionDictionary() {
        this._actions = Reporter.logLevels.reduce(
            (obj, level) =>
                Object.assign(
                    obj,
                    { [level]: [] }
                ),
            {}
        );

        for (let logger of this._loggers) {
            for (let actionLevelNum = 0; actionLevelNum <= 7; actionLevelNum += 1) {
                if (actionLevelNum <= logger.fromLevelNum) {
                    this._actions[Reporter.logLevels[actionLevelNum]].push(logger);
                }
            }
        }
    }


    /**
     * @param {Logger} logger 
     */

    addLogger(logger) {
        this._loggers.push(logger);
        this._rebuildActionDictionary();
    }


    /**
     * Report a message
     * @function report
     * @param {LogObject} log
     */

    async report({ msg, level = 'debug', source }) {
        return Promise.all(
            this._actions[level].map(
                logger =>
                    logger.log({ msg, level, source })
            )
        );
    }
}

export { Reporter }