"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const JSON = require("circular-json");
const configService_1 = require("./configService");
var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["none"] = 0] = "none";
    LogLevel[LogLevel["info"] = 1] = "info";
    LogLevel[LogLevel["warn"] = 2] = "warn";
    LogLevel[LogLevel["debug"] = 4] = "debug";
    LogLevel[LogLevel["error"] = 8] = "error";
    LogLevel[LogLevel["all"] = 15] = "all";
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
class ConsoleLogger {
    /* tslint:disable:max-line-length */
    /* tslint:disable:no-console */
    /* tslint:disable:no-bitwise */
    debug(message) { if (LoggingService.logLevel & LogLevel.debug) {
        console.log(`${LoggingService.moduleName} (debug): ${message}`);
    } }
    info(message) { if (LoggingService.logLevel & LogLevel.info) {
        console.log(`${LoggingService.moduleName} (info): ${message}`);
    } }
    warn(message) { if (LoggingService.logLevel & LogLevel.warn) {
        console.log(`${LoggingService.moduleName} (warn): ${message}`);
    } }
    error(message) { if (LoggingService.logLevel & LogLevel.error) {
        console.log(`${LoggingService.moduleName} (error): ${message}`);
    } }
}
class LoggingService {
    static debug(message) {
        LoggingService.loggers.forEach((logger) => {
            logger.debug(message);
        });
    }
    static info(message) {
        LoggingService.loggers.forEach((logger) => {
            logger.info(message);
        });
    }
    static warn(message) {
        LoggingService.loggers.forEach((logger) => {
            logger.warn(message);
        });
    }
    static error(message) {
        LoggingService.loggers.forEach((logger) => {
            logger.error(message);
        });
    }
    /**
     * Log a message at potentially multiple levels instead of just one.
     *
     * The message will be logged just once, at the first log level in the intersection between
     * the given log level and the current log level, in the following order of precendence:
     *
     *  1. error
     *  2. warn
     *  3. info
     *  4. debug
     *
     * So if the current log level is info|error and you call `message("a message", LogLevel.info|LogLevel.error)`
     * then you will see the message logged as an error.
     *
     * @param message
     * @param level log level(s)
     */
    static message(message, level = LoggingService.logLevel) {
        if (level === LogLevel.none) {
            return;
        }
        // only issue the message once
        let messaged = false;
        /* tslint:disable:no-bitwise */
        if (level & LogLevel.error) {
            LoggingService.error(message);
            messaged = true;
        }
        if (!messaged && (level & LogLevel.warn)) {
            LoggingService.warn(message);
            messaged = true;
        }
        if (!messaged && (level & LogLevel.info)) {
            LoggingService.info(message);
            messaged = true;
        }
        if (!messaged && (level & LogLevel.debug)) {
            LoggingService.debug(message);
        }
        /* tslint:enable:no-bitwise */
    }
    static addLogger(logger) {
        LoggingService.loggers.push(logger);
    }
    static removeLogger(logger) {
        const ndx = LoggingService.loggers.indexOf(logger);
        if (ndx >= 0) {
            LoggingService.loggers.splice(ndx, 1);
        }
    }
    static stringifyObject(obj) {
        return JSON.stringify(obj);
    }
}
LoggingService.loggers = [new ConsoleLogger()];
LoggingService.logLevel = parseInt(configService_1.ConfigService.get("logLevel"), 10);
LoggingService.moduleName = "Arc.js";
exports.LoggingService = LoggingService;
//# sourceMappingURL=loggingService.js.map