import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { localize2WithPath, localizeWithPath } from '../../../../nls.js';
import { Action } from '../../../../base/common/actions.js';
import { isLogLevel, LogLevel, LogLevelToLocalizedString, ILoggerService } from '../../../../platform/log/common/log.js';
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';
import { URI } from '../../../../base/common/uri.js';
import '../../../../platform/files/common/files.js';
import '../../../../platform/instantiation/common/instantiation.js';
import { basename, dirname, isEqual } from '../../../../base/common/resources.js';
import '../../../services/editor/common/editorGroupsService.js';
import { IOutputService } from '../../../services/output/common/output.js';
import { telemetryLogId, extensionTelemetryLogChannelId } from '../../../../platform/telemetry/common/telemetryUtils.js';
import { IDefaultLogLevelsService } from './defaultLogLevels.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { DisposableStore } from '../../../../base/common/lifecycle.js';
var SetLogLevelAction_1;
let SetLogLevelAction = class SetLogLevelAction extends Action {
    static { SetLogLevelAction_1 = this; }
    static { this.ID = 'workbench.action.setLogLevel'; }
    static { this.TITLE = ( localize2WithPath(
        'vs/workbench/contrib/logs/common/logsActions',
        'setLogLevel',
        "Set Log Level..."
    )); }
    constructor(id, label, quickInputService, loggerService, outputService, defaultLogLevelsService) {
        super(id, label);
        this.quickInputService = quickInputService;
        this.loggerService = loggerService;
        this.outputService = outputService;
        this.defaultLogLevelsService = defaultLogLevelsService;
    }
    async run() {
        const logLevelOrChannel = await this.selectLogLevelOrChannel();
        if (logLevelOrChannel !== null) {
            if (isLogLevel(logLevelOrChannel)) {
                this.loggerService.setLogLevel(logLevelOrChannel);
            }
            else {
                await this.setLogLevelForChannel(logLevelOrChannel);
            }
        }
    }
    async selectLogLevelOrChannel() {
        const defaultLogLevels = await this.defaultLogLevelsService.getDefaultLogLevels();
        const extensionLogs = [], logs = [];
        const logLevel = this.loggerService.getLogLevel();
        for (const channel of this.outputService.getChannelDescriptors()) {
            if (!SetLogLevelAction_1.isLevelSettable(channel) || !channel.file) {
                continue;
            }
            const channelLogLevel = this.loggerService.getLogLevel(channel.file) ?? logLevel;
            const item = { id: channel.id, resource: channel.file, label: channel.label, description: channelLogLevel !== logLevel ? this.getLabel(channelLogLevel) : undefined, extensionId: channel.extensionId };
            if (channel.extensionId) {
                extensionLogs.push(item);
            }
            else {
                logs.push(item);
            }
        }
        const entries = [];
        entries.push({ type: 'separator', label: ( localizeWithPath('vs/workbench/contrib/logs/common/logsActions', 'all', "All")) });
        entries.push(...this.getLogLevelEntries(defaultLogLevels.default, this.loggerService.getLogLevel(), true));
        if (extensionLogs.length) {
            entries.push({ type: 'separator', label: ( localizeWithPath(
                'vs/workbench/contrib/logs/common/logsActions',
                'extensionLogs',
                "Extension Logs"
            )) });
            entries.push(...extensionLogs.sort((a, b) => a.label.localeCompare(b.label)));
        }
        entries.push({ type: 'separator', label: ( localizeWithPath('vs/workbench/contrib/logs/common/logsActions', 'loggers', "Logs")) });
        entries.push(...logs.sort((a, b) => a.label.localeCompare(b.label)));
        return ( new Promise((resolve, reject) => {
            const disposables = ( new DisposableStore());
            const quickPick = this.quickInputService.createQuickPick();
            quickPick.placeholder = ( localizeWithPath(
                'vs/workbench/contrib/logs/common/logsActions',
                'selectlog',
                "Set Log Level"
            ));
            quickPick.items = entries;
            let selectedItem;
            disposables.add(quickPick.onDidTriggerItemButton(e => {
                quickPick.hide();
                this.defaultLogLevelsService.setDefaultLogLevel(e.item.level);
            }));
            disposables.add(quickPick.onDidAccept(e => {
                selectedItem = quickPick.selectedItems[0];
                quickPick.hide();
            }));
            disposables.add(quickPick.onDidHide(() => {
                const result = selectedItem ? selectedItem.level ?? selectedItem : null;
                disposables.dispose();
                resolve(result);
            }));
            quickPick.show();
        }));
    }
    static isLevelSettable(channel) {
        return channel.log && channel.file !== undefined && channel.id !== telemetryLogId && channel.id !== extensionTelemetryLogChannelId;
    }
    async setLogLevelForChannel(logChannel) {
        const defaultLogLevels = await this.defaultLogLevelsService.getDefaultLogLevels();
        const defaultLogLevel = defaultLogLevels.extensions.find(e => e[0] === logChannel.extensionId?.toLowerCase())?.[1] ?? defaultLogLevels.default;
        const currentLogLevel = this.loggerService.getLogLevel(logChannel.resource) ?? defaultLogLevel;
        const entries = this.getLogLevelEntries(defaultLogLevel, currentLogLevel, !!logChannel.extensionId);
        return ( new Promise((resolve, reject) => {
            const disposables = ( new DisposableStore());
            const quickPick = this.quickInputService.createQuickPick();
            quickPick.placeholder = logChannel ? ( localizeWithPath(
                'vs/workbench/contrib/logs/common/logsActions',
                'selectLogLevelFor',
                " {0}: Select log level",
                logChannel?.label
            )) : ( localizeWithPath(
                'vs/workbench/contrib/logs/common/logsActions',
                'selectLogLevel',
                "Select log level"
            ));
            quickPick.items = entries;
            quickPick.activeItems = entries.filter((entry) => entry.level === this.loggerService.getLogLevel());
            let selectedItem;
            disposables.add(quickPick.onDidTriggerItemButton(e => {
                quickPick.hide();
                this.defaultLogLevelsService.setDefaultLogLevel(e.item.level, logChannel.extensionId);
            }));
            disposables.add(quickPick.onDidAccept(e => {
                selectedItem = quickPick.selectedItems[0];
                quickPick.hide();
            }));
            disposables.add(quickPick.onDidHide(() => {
                if (selectedItem) {
                    this.loggerService.setLogLevel(logChannel.resource, selectedItem.level);
                }
                disposables.dispose();
                resolve();
            }));
            quickPick.show();
        }));
    }
    getLogLevelEntries(defaultLogLevel, currentLogLevel, canSetDefaultLogLevel) {
        const button = canSetDefaultLogLevel ? { iconClass: ThemeIcon.asClassName(Codicon.checkAll), tooltip: ( localizeWithPath(
            'vs/workbench/contrib/logs/common/logsActions',
            'resetLogLevel',
            "Set as Default Log Level"
        )) } : undefined;
        return [
            { label: this.getLabel(LogLevel.Trace, currentLogLevel), level: LogLevel.Trace, description: this.getDescription(LogLevel.Trace, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Trace ? [button] : undefined },
            { label: this.getLabel(LogLevel.Debug, currentLogLevel), level: LogLevel.Debug, description: this.getDescription(LogLevel.Debug, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Debug ? [button] : undefined },
            { label: this.getLabel(LogLevel.Info, currentLogLevel), level: LogLevel.Info, description: this.getDescription(LogLevel.Info, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Info ? [button] : undefined },
            { label: this.getLabel(LogLevel.Warning, currentLogLevel), level: LogLevel.Warning, description: this.getDescription(LogLevel.Warning, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Warning ? [button] : undefined },
            { label: this.getLabel(LogLevel.Error, currentLogLevel), level: LogLevel.Error, description: this.getDescription(LogLevel.Error, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Error ? [button] : undefined },
            { label: this.getLabel(LogLevel.Off, currentLogLevel), level: LogLevel.Off, description: this.getDescription(LogLevel.Off, defaultLogLevel), buttons: button && defaultLogLevel !== LogLevel.Off ? [button] : undefined },
        ];
    }
    getLabel(level, current) {
        const label = LogLevelToLocalizedString(level).value;
        return level === current ? `$(check) ${label}` : label;
    }
    getDescription(level, defaultLogLevel) {
        return defaultLogLevel === level ? ( localizeWithPath('vs/workbench/contrib/logs/common/logsActions', 'default', "Default")) : undefined;
    }
};
SetLogLevelAction = SetLogLevelAction_1 = ( __decorate([
    ( __param(2, IQuickInputService)),
    ( __param(3, ILoggerService)),
    ( __param(4, IOutputService)),
    ( __param(5, IDefaultLogLevelsService))
], SetLogLevelAction));
(class OpenWindowSessionLogFileAction extends Action {
    static { this.ID = 'workbench.action.openSessionLogFile'; }
    static { this.TITLE = ( localize2WithPath(
        'vs/workbench/contrib/logs/common/logsActions',
        'openSessionLogFile',
        "Open Window Log File (Session)..."
    )); }
    constructor(id, label, environmentService, fileService, quickInputService, editorService) {
        super(id, label);
        this.environmentService = environmentService;
        this.fileService = fileService;
        this.quickInputService = quickInputService;
        this.editorService = editorService;
    }
    async run() {
        const sessionResult = await this.quickInputService.pick(this.getSessions().then(sessions => ( sessions.map((s, index) => ({
            id: ( s.toString()),
            label: basename(s),
            description: index === 0 ? ( localizeWithPath('vs/workbench/contrib/logs/common/logsActions', 'current', "Current")) : undefined
        })))), {
            canPickMany: false,
            placeHolder: ( localizeWithPath(
                'vs/workbench/contrib/logs/common/logsActions',
                'sessions placeholder',
                "Select Session"
            ))
        });
        if (sessionResult) {
            const logFileResult = await this.quickInputService.pick(this.getLogFiles(( URI.parse(sessionResult.id))).then(logFiles => ( logFiles.map(s => ({
                id: ( s.toString()),
                label: basename(s)
            })))), {
                canPickMany: false,
                placeHolder: ( localizeWithPath(
                    'vs/workbench/contrib/logs/common/logsActions',
                    'log placeholder',
                    "Select Log file"
                ))
            });
            if (logFileResult) {
                return this.editorService.openEditor({ resource: ( URI.parse(logFileResult.id)), options: { pinned: true } }).then(() => undefined);
            }
        }
    }
    async getSessions() {
        const logsPath = this.environmentService.logsHome.with({ scheme: this.environmentService.logFile.scheme });
        const result = [logsPath];
        const stat = await this.fileService.resolve(dirname(logsPath));
        if (stat.children) {
            result.push(...( stat.children
                .filter(stat => !isEqual(stat.resource, logsPath) && stat.isDirectory && /^\d{8}T\d{6}$/.test(stat.name))
                .sort()
                .reverse()
                .map(d => d.resource)));
        }
        return result;
    }
    async getLogFiles(session) {
        const stat = await this.fileService.resolve(session);
        if (stat.children) {
            return ( stat.children.filter(stat => !stat.isDirectory).map(stat => stat.resource));
        }
        return [];
    }
});
export { SetLogLevelAction };
