"use strict";
var _MainThreadCommands_proxy;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainThreadCommands = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_connection_1 = require("@opensumi/ide-connection");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const command_1 = require("@opensumi/ide-monaco/lib/browser/contrib/command");
const vscode_1 = require("../../../common/vscode");
const { isNonEmptyArray } = ide_core_common_1.arrays;
let MainThreadCommands = class MainThreadCommands {
    constructor(rpcProtocol) {
        this.rpcProtocol = rpcProtocol;
        _MainThreadCommands_proxy.set(this, void 0);
        this.commands = new Map();
        this.argumentProcessors = [];
        this.disposable = new ide_core_common_1.Disposable();
        tslib_1.__classPrivateFieldSet(this, _MainThreadCommands_proxy, this.rpcProtocol.getProxy(vscode_1.ExtHostAPIIdentifier.ExtHostCommands), "f");
        tslib_1.__classPrivateFieldGet(this, _MainThreadCommands_proxy, "f").$registerBuiltInCommands();
        tslib_1.__classPrivateFieldGet(this, _MainThreadCommands_proxy, "f").$registerCommandConverter();
        this.registerUriArgProcessor();
    }
    registerUriArgProcessor() {
        this.disposable.addDispose(this.registerArgumentProcessor({
            processArgument: (arg) => {
                if (arg instanceof ide_core_common_1.URI) {
                    return arg.codeUri;
                }
                // 数组参数的处理
                if (isNonEmptyArray(arg)) {
                    return arg.map((item) => {
                        if (item instanceof ide_core_common_1.URI) {
                            return item.codeUri;
                        }
                        return item;
                    });
                }
                return arg;
            },
        }));
    }
    dispose() {
        this.commands.forEach((comamnd) => {
            comamnd.dispose();
        });
        this.commands.clear();
        this.disposable.dispose();
    }
    registerArgumentProcessor(processor) {
        this.argumentProcessors.push(processor);
        return ide_core_common_1.Disposable.create(() => {
            const idx = this.argumentProcessors.indexOf(processor);
            if (idx >= 0) {
                this.argumentProcessors.splice(idx, 1);
            }
        });
    }
    $registerCommand(id) {
        const proxy = tslib_1.__classPrivateFieldGet(this, _MainThreadCommands_proxy, "f");
        const execute = (...args) => {
            args = args.map((arg) => this.argumentProcessors.reduce((r, p) => p.processArgument(r), arg));
            return proxy.$executeContributedCommand(id, ...args);
        };
        const disposer = new ide_core_common_1.Disposable();
        const extCommandHandler = {
            execute,
            dispose: () => disposer.dispose(),
        };
        const command = this.commandRegistry.getCommand(id);
        if (command) {
            // 如果已经有对应的命令则注册为 handler
            // 后面注册的命令会覆盖前面注册的的命令
            disposer.addDispose(this.commandRegistry.registerHandler(id, { execute }));
        }
        else {
            disposer.addDispose(this.commandRegistry.registerCommand({ id }, { execute }));
        }
        this.commands.set(id, extCommandHandler);
    }
    $unregisterCommand(id) {
        const command = this.commands.get(id);
        if (command) {
            command.dispose();
            this.commands.delete(id);
        }
    }
    $getCommands() {
        return Promise.resolve(this.commandRegistry.getCommands().map((command) => command.id));
    }
    /**
     * 来自main -> extHost的command调用
     */
    $executeExtensionCommand(id, ...args) {
        if (this.commands.has(id)) {
            return this.commands.get(id).execute(...args);
        }
        else {
            args = args.map((arg) => this.argumentProcessors.reduce((r, p) => p.processArgument(r), arg));
            return tslib_1.__classPrivateFieldGet(this, _MainThreadCommands_proxy, "f").$executeContributedCommand(id, ...args);
        }
    }
    $executeCommandWithExtensionInfo(id, extensionInfo, ...args) {
        const isPermitted = this.commandRegistry.isPermittedCommand(id, extensionInfo, ...args);
        if (!isPermitted) {
            throw new Error(`Extension ${extensionInfo.id} has not permit to execute ${id}`);
        }
        return this.$executeCommand(id, ...args);
    }
    async $executeCommand(id, ...args) {
        try {
            return await this.monacoCommandService.executeCommand(id, ...args);
        }
        catch (e) {
            this.logger.error(e);
            throw e;
        }
    }
};
exports.MainThreadCommands = MainThreadCommands;
_MainThreadCommands_proxy = new WeakMap();
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.CommandRegistry),
    tslib_1.__metadata("design:type", Object)
], MainThreadCommands.prototype, "commandRegistry", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(command_1.ICommandServiceToken),
    tslib_1.__metadata("design:type", Object)
], MainThreadCommands.prototype, "monacoCommandService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.ILogger),
    tslib_1.__metadata("design:type", Object)
], MainThreadCommands.prototype, "logger", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IContextKeyService),
    tslib_1.__metadata("design:type", Object)
], MainThreadCommands.prototype, "contextKeyService", void 0);
exports.MainThreadCommands = MainThreadCommands = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__param(0, (0, di_1.Optional)(ide_connection_1.IRPCProtocol)),
    tslib_1.__metadata("design:paramtypes", [Object])
], MainThreadCommands);
//# sourceMappingURL=main.thread.commands.js.map