/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
/*
 * Copyright (C) 2017, 2018 TypeFox and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 */
/* eslint-disable @typescript-eslint/no-unnecessary-qualifier */
import lsp from 'vscode-languageserver';
export var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["Error"] = 0] = "Error";
    LogLevel[LogLevel["Warning"] = 1] = "Warning";
    LogLevel[LogLevel["Info"] = 2] = "Info";
    LogLevel[LogLevel["Log"] = 3] = "Log";
})(LogLevel = LogLevel || (LogLevel = {}));
(function (LogLevel) {
    function fromString(value) {
        switch (value?.toLowerCase()) {
            case 'log':
                return LogLevel.Log;
            case 'info':
                return LogLevel.Info;
            case 'warning':
                return LogLevel.Warning;
            case 'error':
            default:
                return LogLevel.Error;
        }
    }
    LogLevel.fromString = fromString;
    function toString(level) {
        switch (level) {
            case LogLevel.Error:
                return 'error';
            case LogLevel.Warning:
                return 'warning';
            case LogLevel.Info:
                return 'info';
            case LogLevel.Log:
                return 'log';
        }
    }
    LogLevel.toString = toString;
})(LogLevel = LogLevel || (LogLevel = {}));
export class LspClientLogger {
    constructor(client, level) {
        this.client = client;
        this.level = level;
    }
    sendMessage(severity, messageObjects, options) {
        if (this.level >= severity || options?.overrideLevel) {
            const message = messageObjects.map(p => {
                if (typeof p === 'object') {
                    return JSON.stringify(p, null, 2);
                }
                else {
                    return p;
                }
            }).join(' ');
            this.client.logMessage({
                type: severity,
                message: message,
            });
        }
    }
    logLevelToLspMessageType(level) {
        switch (level) {
            case LogLevel.Log:
                return lsp.MessageType.Log;
            case LogLevel.Info:
                return lsp.MessageType.Info;
            case LogLevel.Warning:
                return lsp.MessageType.Warning;
            case LogLevel.Error:
                return lsp.MessageType.Error;
        }
    }
    error(...args) {
        this.sendMessage(lsp.MessageType.Error, args);
    }
    warn(...args) {
        this.sendMessage(lsp.MessageType.Warning, args);
    }
    info(...args) {
        this.sendMessage(lsp.MessageType.Info, args);
    }
    log(...args) {
        this.sendMessage(lsp.MessageType.Log, args);
    }
    logIgnoringVerbosity(level, ...args) {
        this.sendMessage(this.logLevelToLspMessageType(level), args, { overrideLevel: true });
    }
    trace(level, message, data) {
        this.logIgnoringVerbosity(LogLevel.Log, `[${level}  - ${now()}] ${message}`);
        if (data) {
            this.logIgnoringVerbosity(LogLevel.Log, data2String(data));
        }
    }
}
export class ConsoleLogger {
    constructor(level = LogLevel.Error) {
        this.level = level;
    }
    print(level, args, options) {
        if (this.level >= level || options?.overrideLevel) {
            // All messages logged to stderr as stdout is reserved for LSP communication.
            console.error(`[${LogLevel.toString(level)}]`, ...this.toStrings(...args));
        }
    }
    toStrings(...args) {
        return args.map(a => {
            if (typeof a === 'string') {
                return a;
            }
            return JSON.stringify(a, null, 2);
        });
    }
    error(...args) {
        this.print(LogLevel.Error, args);
    }
    warn(...args) {
        this.print(LogLevel.Warning, args);
    }
    info(...args) {
        this.print(LogLevel.Info, args);
    }
    log(...args) {
        this.print(LogLevel.Log, args);
    }
    logIgnoringVerbosity(level, ...args) {
        this.print(level, args, { overrideLevel: true });
    }
    trace(level, message, data) {
        this.logIgnoringVerbosity(LogLevel.Log, `[${level}  - ${now()}] ${message}`);
        if (data) {
            this.logIgnoringVerbosity(LogLevel.Log, data2String(data));
        }
    }
}
export class PrefixingLogger {
    constructor(logger, prefix) {
        this.logger = logger;
        this.prefix = prefix;
    }
    error(...args) {
        this.logger.error(this.prefix, ...args);
    }
    warn(...args) {
        this.logger.warn(this.prefix, ...args);
    }
    info(...args) {
        this.logger.info(this.prefix, ...args);
    }
    log(...args) {
        this.logger.log(this.prefix, ...args);
    }
    logIgnoringVerbosity(level, ...args) {
        this.logger.logIgnoringVerbosity(level, this.prefix, ...args);
    }
    trace(level, message, data) {
        this.logIgnoringVerbosity(LogLevel.Log, this.prefix, `[${level}  - ${now()}] ${message}`);
        if (data) {
            this.logIgnoringVerbosity(LogLevel.Log, this.prefix, data2String(data));
        }
    }
}
function now() {
    const now = new Date();
    return padLeft(`${now.getUTCHours()}`, 2, '0')
        + ':' + padLeft(`${now.getMinutes()}`, 2, '0')
        + ':' + padLeft(`${now.getUTCSeconds()}`, 2, '0') + `.${now.getMilliseconds()}`;
}
function padLeft(s, n, pad = ' ') {
    return pad.repeat(Math.max(0, n - s.length)) + s;
}
function data2String(data) {
    if (data instanceof Error) {
        return data.stack || data.message;
    }
    if (data.success === false && data.message) {
        return data.message;
    }
    return data.toString();
}
//# sourceMappingURL=logger.js.map