"use strict";
var _OutputChannelImpl_proxy;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogOutputChannelImpl = exports.OutputChannelImpl = exports.ExtHostOutput = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const vscode_1 = require("../../../common/vscode");
const types = tslib_1.__importStar(require("../../../common/vscode/ext-types"));
class ExtHostOutput {
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
    }
    createOutputChannel(name, optionsOrLangId) {
        name = name.trim();
        if (!name) {
            throw new Error('illegal argument `name`. must not be falsy');
        }
        let log = false;
        let languageId;
        if (typeof optionsOrLangId === 'object') {
            log = !!optionsOrLangId.log;
            languageId = optionsOrLangId.languageId;
        }
        else if ((0, ide_core_common_1.isString)(optionsOrLangId)) {
            languageId = optionsOrLangId;
        }
        if ((0, ide_core_common_1.isString)(languageId) && !languageId.trim()) {
            throw new Error('illegal argument `languageId`. must not be empty');
        }
        const logLevel = types.OutputChannelLogLevel.Info;
        let instance;
        if (log) {
            instance = new LogOutputChannelImpl(name, this.rpcProtocol, logLevel);
        }
        else {
            instance = new OutputChannelImpl(name, this.rpcProtocol);
        }
        if (languageId) {
            instance.setLanguageId(languageId);
        }
        return instance;
    }
}
exports.ExtHostOutput = ExtHostOutput;
// 批处理字符最大长度
const OUTPUT_BATCH_MAX_SIZE = 20 * 1024;
// 批处理延时
const OUTPUT_BATCH_DURATION_MS = 5;
class OutputChannelImpl {
    constructor(name, rpcProtocol) {
        this.name = name;
        _OutputChannelImpl_proxy.set(this, void 0);
        this.batchedOutputLine = '';
        this.batchedTimer = null;
        tslib_1.__classPrivateFieldSet(this, _OutputChannelImpl_proxy, rpcProtocol.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadOutput), "f");
    }
    replace(value) {
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$replace(this.name, value);
    }
    dispose() {
        if (!this.disposed) {
            tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$dispose(this.name).then(() => {
                this.disposed = true;
            });
        }
    }
    append(value) {
        this.validate();
        const data = this.batchedOutputLine + value;
        this.batchedOutputLine = data;
        if (this.batchedOutputLine.length >= OUTPUT_BATCH_MAX_SIZE) {
            this.flushOutputString();
        }
        if (!this.batchedTimer) {
            this.batchedTimer = setTimeout(() => this.flushOutputString(), OUTPUT_BATCH_DURATION_MS);
        }
    }
    appendLine(value) {
        this.validate();
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$appendLine(this.name, value);
    }
    clear() {
        this.validate();
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$clear(this.name);
    }
    flushOutputString() {
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$append(this.name, this.batchedOutputLine);
        this.batchedOutputLine = '';
        if (this.batchedTimer) {
            clearTimeout(this.batchedTimer);
            this.batchedTimer = null;
        }
    }
    show(preserveFocus) {
        this.validate();
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$reveal(this.name, !!preserveFocus);
    }
    hide() {
        this.validate();
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$close(this.name);
    }
    setLanguageId(languageId) {
        tslib_1.__classPrivateFieldGet(this, _OutputChannelImpl_proxy, "f").$setLanguageId(this.name, languageId);
    }
    validate() {
        if (this.disposed) {
            throw new Error('Channel has been closed');
        }
    }
}
exports.OutputChannelImpl = OutputChannelImpl;
_OutputChannelImpl_proxy = new WeakMap();
class LogOutputChannelImpl extends OutputChannelImpl {
    constructor(name, rpcProtocol, logLevel) {
        super(name, rpcProtocol);
        this.logLevel = types.OutputChannelLogLevel.Info;
        this.onDidChangeLogLevelEmitter = new ide_core_common_1.Emitter();
        this.onDidChangeLogLevel = this.onDidChangeLogLevelEmitter.event;
        this.logLevel = logLevel;
        this.trace = this.trace.bind(this);
        this.debug = this.debug.bind(this);
        this.info = this.info.bind(this);
        this.warn = this.warn.bind(this);
        this.error = this.error.bind(this);
    }
    data2String(data) {
        if (data instanceof Error) {
            return (0, ide_core_common_1.getErrorMessage)(data);
        }
        if (data.success === false && data.message) {
            return data.message;
        }
        return data.toString();
    }
    now() {
        const twoDigits = (v) => (v < 10 ? `0${v}` : v);
        const threeDigits = (v) => (v < 10 ? `00${v}` : v < 100 ? `0${v}` : v);
        const now = new Date();
        const date = `${now.getFullYear()}-${twoDigits(now.getMonth() + 1)}-${twoDigits(now.getDate())}`;
        const time = `${twoDigits(now.getHours())}:${twoDigits(now.getMinutes())}:${twoDigits(now.getSeconds())}.${threeDigits(now.getMilliseconds())}`;
        return `${date} ${time}`;
    }
    label(level) {
        switch (level) {
            case types.OutputChannelLogLevel.Trace:
                return 'trace';
            case types.OutputChannelLogLevel.Error:
                return 'error';
            case types.OutputChannelLogLevel.Warning:
                return 'warning';
            case types.OutputChannelLogLevel.Info:
                return 'info';
            case types.OutputChannelLogLevel.Debug:
                return 'debug';
            default:
                return '';
        }
    }
    logWithLevel(level, message, data) {
        this.appendLine(`${this.now()} [${this.label(level)}] ${message}`);
        if (data) {
            this.append(this.data2String(data));
        }
    }
    trace(message, ...args) {
        this.logWithLevel(types.OutputChannelLogLevel.Trace, message, args);
    }
    debug(message, ...args) {
        this.logWithLevel(types.OutputChannelLogLevel.Debug, message, args);
    }
    info(message, ...args) {
        this.logWithLevel(types.OutputChannelLogLevel.Info, message, args);
    }
    warn(message, ...args) {
        this.logWithLevel(types.OutputChannelLogLevel.Warning, message, args);
    }
    error(error, ...args) {
        this.logWithLevel(types.OutputChannelLogLevel.Error, error.toString(), args);
    }
}
exports.LogOutputChannelImpl = LogOutputChannelImpl;
//# sourceMappingURL=ext.host.output.js.map