"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = exports.Logger = exports.DEFAULT_LOG_LEVEL = exports.LOG_LEVELS = exports.LOG_LEVEL_ENV_VAR = void 0;
exports.setLogConnection = setLogConnection;
exports.setLogLevel = setLogLevel;
exports.getLogLevelFromEnvironment = getLogLevelFromEnvironment;
const LSP = require("vscode-languageserver");
exports.LOG_LEVEL_ENV_VAR = 'BASH_IDE_LOG_LEVEL';
exports.LOG_LEVELS = ['debug', 'info', 'warning', 'error'];
exports.DEFAULT_LOG_LEVEL = 'info';
const LOG_LEVELS_TO_MESSAGE_TYPES = {
    debug: LSP.MessageType.Log,
    info: LSP.MessageType.Info,
    warning: LSP.MessageType.Warning,
    error: LSP.MessageType.Error,
};
// Singleton madness to allow for logging from anywhere in the codebase
let _connection = null;
let _logLevel = getLogLevelFromEnvironment();
/**
 * Set the log connection. Should be done at startup.
 */
function setLogConnection(connection) {
    _connection = connection;
}
/**
 * Set the minimum log level.
 */
function setLogLevel(logLevel) {
    _logLevel = LOG_LEVELS_TO_MESSAGE_TYPES[logLevel];
}
class Logger {
    constructor({ prefix = '' } = {}) {
        this.prefix = prefix;
    }
    log(severity, messageObjects) {
        if (_logLevel < severity) {
            return;
        }
        if (!_connection) {
            // eslint-disable-next-line no-console
            console.warn(`The logger's LSP Connection is not set. Dropping messages`);
            return;
        }
        const formattedMessage = messageObjects
            .map((p) => {
            if (p instanceof Error) {
                return p.stack || p.message;
            }
            if (typeof p === 'object') {
                return JSON.stringify(p, null, 2);
            }
            return p;
        })
            .join(' ');
        const level = Logger.MESSAGE_TYPE_TO_LOG_LEVEL_MSG[severity];
        const prefix = this.prefix ? `${this.prefix} - ` : '';
        const time = new Date().toISOString().substring(11, 23);
        const message = `${time} ${level} ${prefix}${formattedMessage}`;
        _connection.sendNotification(LSP.LogMessageNotification.type, {
            type: severity,
            message,
        });
    }
    debug(message, ...additionalArgs) {
        this.log(LSP.MessageType.Log, [message, ...additionalArgs]);
    }
    info(message, ...additionalArgs) {
        this.log(LSP.MessageType.Info, [message, ...additionalArgs]);
    }
    warn(message, ...additionalArgs) {
        this.log(LSP.MessageType.Warning, [message, ...additionalArgs]);
    }
    error(message, ...additionalArgs) {
        this.log(LSP.MessageType.Error, [message, ...additionalArgs]);
    }
}
exports.Logger = Logger;
Logger.MESSAGE_TYPE_TO_LOG_LEVEL_MSG = {
    [LSP.MessageType.Error]: 'ERROR ⛔️',
    [LSP.MessageType.Warning]: 'WARNING ⛔️',
    [LSP.MessageType.Info]: 'INFO',
    [LSP.MessageType.Log]: 'DEBUG',
};
/**
 * Default logger.
 */
exports.logger = new Logger();
/**
 * Get the log level from the environment, before the server initializes.
 * Should only be used internally.
 */
function getLogLevelFromEnvironment() {
    const logLevelFromEnvironment = process.env[exports.LOG_LEVEL_ENV_VAR];
    if (logLevelFromEnvironment) {
        const logLevel = LOG_LEVELS_TO_MESSAGE_TYPES[logLevelFromEnvironment];
        if (logLevel) {
            return logLevel;
        }
        // eslint-disable-next-line no-console
        console.warn(`Invalid ${exports.LOG_LEVEL_ENV_VAR} "${logLevelFromEnvironment}", expected one of: ${Object.keys(LOG_LEVELS_TO_MESSAGE_TYPES).join(', ')}`);
    }
    return LOG_LEVELS_TO_MESSAGE_TYPES[exports.DEFAULT_LOG_LEVEL];
}
//# sourceMappingURL=logger.js.map