"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtensionCommandContribution = exports.ExtensionClientAppContribution = exports.getClientId = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const ide_core_browser_1 = require("@opensumi/ide-core-browser");
const status_bar_service_1 = require("@opensumi/ide-core-browser/lib/services/status-bar-service");
const ide_editor_1 = require("@opensumi/ide-editor");
const editor_1 = require("@opensumi/ide-editor/lib/common/editor");
const ide_overlay_1 = require("@opensumi/ide-overlay");
const ide_webview_1 = require("@opensumi/ide-webview");
const common_1 = require("../common");
const converter_1 = require("../common/vscode/converter");
const types_1 = require("./types");
const VSCodeBuiltinCommands = tslib_1.__importStar(require("./vscode/builtin-commands"));
const walkthroughs_service_1 = require("./walkthroughs.service");
const getClientId = (injector) => {
    const service = injector.get(ide_core_browser_1.IApplicationService);
    return service.clientId;
};
exports.getClientId = getClientId;
let ExtensionClientAppContribution = class ExtensionClientAppContribution {
    initialize() {
        this.extensionService.activate().then(() => {
            const disposer = this.webviewService.registerWebviewReviver({
                handles: () => 0,
                revive: async (id) => new Promise((resolve) => {
                    this.eventBus.on(types_1.ExtensionApiReadyEvent, () => {
                        disposer.dispose();
                        resolve(this.webviewService.tryReviveWebviewComponent(id));
                    });
                }),
            });
        });
    }
    async onStart() {
        (0, ide_core_browser_1.runWhenIdle)(() => {
            this.extensionService.runExtensionContributes();
        });
        this.preferenceSettingsService.registerSettingGroup({
            id: 'extension',
            title: (0, ide_core_browser_1.localize)('settings.group.extension'),
            iconClass: (0, ide_core_browser_1.getIcon)('extension'),
        });
    }
    onDisposeSideEffects() {
        /**
         * IDE 关闭或者刷新时销毁插件进程
         * 最好在这里直接关掉插件进程，调用链路太长可能导致请求调不到后端
         */
        this.extensionNodeClient.disposeClientExtProcess(this.clientId, false);
    }
    // restart extProcess on reconnect
    onReconnect() {
        this.extensionService.restartExtProcess(common_1.ERestartPolicy.WhenExit);
    }
    /**
     * 当前客户端 id
     */
    get clientId() {
        return (0, exports.getClientId)(this.injector);
    }
};
exports.ExtensionClientAppContribution = ExtensionClientAppContribution;
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IPreferenceSettingsService),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "preferenceSettingsService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(di_1.INJECTOR_TOKEN),
    tslib_1.__metadata("design:type", di_1.Injector)
], ExtensionClientAppContribution.prototype, "injector", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionNodeServiceServerPath),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "extensionNodeClient", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.QuickOpenService),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "quickOpenService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(status_bar_service_1.IStatusBarService),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "statusBar", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IEventBus),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "eventBus", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_webview_1.IWebviewService),
    tslib_1.__metadata("design:type", Object)
], ExtensionClientAppContribution.prototype, "webviewService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionService),
    tslib_1.__metadata("design:type", common_1.ExtensionService)
], ExtensionClientAppContribution.prototype, "extensionService", void 0);
exports.ExtensionClientAppContribution = ExtensionClientAppContribution = tslib_1.__decorate([
    (0, ide_core_browser_1.Domain)(ide_core_browser_1.ClientAppContribution)
], ExtensionClientAppContribution);
let ExtensionCommandContribution = class ExtensionCommandContribution {
    registerCommands(registry) {
        registry.registerCommand({
            id: 'ext.restart',
            label: '%extension.host.restart%',
        }, {
            execute: async () => {
                this.logger.log('start restart ext host process');
                await this.extensionService.restartExtProcess();
                this.logger.log('end restart ext host process');
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.GET_EXTENSION, {
            execute: async (id) => {
                const ext = this.extensionInstanceManageService.getExtensionInstanceByExtId(id);
                return ext && ext.toJSON();
            },
        });
        this.registerVSCBuiltinCommands(registry);
    }
    registerVSCBuiltinCommands(registry) {
        // vscode `setContext` for extensions
        // only works for global scoped context
        registry.registerCommand(VSCodeBuiltinCommands.SET_CONTEXT, {
            execute: (contextKey, contextValue) => {
                this.contextKeyService.createKey(String(contextKey), contextValue);
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.RELOAD_WINDOW_COMMAND, {
            execute: () => {
                this.clientApp.fireOnReload();
            },
        });
        registry.registerCommand(common_1.EMIT_EXT_HOST_EVENT, {
            execute: async (eventName, ...eventArgs) => {
                // activationEvent 添加 onEvent:xxx
                await this.activationEventService.fireEvent('onEvent:' + eventName);
                const results = await this.eventBus.fireAndAwait(new types_1.ExtHostEvent({
                    eventName,
                    eventArgs,
                }));
                const mergedResults = [];
                results.forEach((r) => {
                    if (r.err) {
                        mergedResults.push(r);
                    }
                    else {
                        mergedResults.push(...(r.result || []));
                    }
                });
                return mergedResults;
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.SHOW_RUN_TIME_EXTENSION, {
            execute: async () => {
                const activated = await this.extensionService.getActivatedExtensions();
                this.quickOpenService.open({
                    onType: (_, acceptor) => acceptor(this.asQuickOpenItems(activated)),
                }, {
                    placeholder: '运行中的插件',
                    fuzzyMatchLabel: {
                        enableSeparateSubstringMatching: true,
                    },
                });
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.START_EXTENSION_HOST_PROFILER, {
            execute: async () => {
                if (!this.cpuProfileStatus) {
                    this.cpuProfileStatus = this.statusBar.addElement('ExtensionHostProfile', {
                        tooltip: (0, ide_core_browser_1.formatLocalize)('extension.profiling.clickStop', 'Click to stop profiling.'),
                        text: `$(sync~spin) ${(0, ide_core_browser_1.formatLocalize)('extension.profilingExtensionHost', 'Profiling Extension Host')}`,
                        alignment: status_bar_service_1.StatusBarAlignment.RIGHT,
                        command: VSCodeBuiltinCommands.STOP_EXTENSION_HOST_PROFILER.id,
                    });
                }
                await this.extensionProfiler.$startProfile(this.clientId);
            },
            isPermitted: () => false,
        });
        registry.registerCommand(VSCodeBuiltinCommands.STOP_EXTENSION_HOST_PROFILER, {
            execute: async () => {
                const successful = await this.extensionProfiler.$stopProfile(this.clientId);
                if (this.cpuProfileStatus) {
                    this.cpuProfileStatus.dispose();
                    this.cpuProfileStatus = null;
                }
                if (successful) {
                    const saveUri = await this.dialogService.showSaveDialog({
                        saveLabel: (0, ide_core_browser_1.formatLocalize)('extension.profile.save', 'Save Extension Host Profile'),
                        showNameInput: true,
                        defaultFileName: `CPU-${new Date().toISOString().replace(/[\-:]/g, '')}.cpuprofile`,
                    });
                    if (saveUri === null || saveUri === void 0 ? void 0 : saveUri.codeUri) {
                        await this.extensionProfiler.$saveLastProfile(saveUri === null || saveUri === void 0 ? void 0 : saveUri.codeUri.fsPath);
                    }
                }
            },
            isPermitted: () => false,
        });
        registry.registerCommand(VSCodeBuiltinCommands.COPY_FILE_PATH, {
            execute: async (uri) => {
                await this.commandService.executeCommand(ide_core_browser_1.FILE_COMMANDS.COPY_PATH.id, ide_core_browser_1.URI.from(uri));
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.COPY_RELATIVE_FILE_PATH, {
            execute: async (uri) => {
                await this.commandService.executeCommand(ide_core_browser_1.FILE_COMMANDS.COPY_RELATIVE_PATH.id, ide_core_browser_1.URI.from(uri));
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.OPEN, {
            execute: (uriComponents, columnAndOptions, label) => {
                const uri = ide_core_browser_1.URI.from(uriComponents);
                return this.doOpenWith(uri, columnAndOptions, label, undefined);
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.OPEN_WITH, {
            execute: (resource, id, columnAndOptions) => {
                const uri = ide_core_browser_1.URI.from(resource);
                // 指定使用某种 editor 打开资源，如果 id 传入 default，则使用默认的 editor
                const openType = id === 'default'
                    ? undefined
                    : {
                        type: editor_1.EditorOpenType.component,
                        componentId: `${ide_core_browser_1.CUSTOM_EDITOR_SCHEME}-${id}`,
                    };
                return this.doOpenWith(uri, columnAndOptions, undefined, openType);
            },
        });
        registry.registerCommand(VSCodeBuiltinCommands.DIFF, {
            execute: (left, right, title, options) => {
                // const enableHideUnchanged = this.preferenceService.get('diffEditor.hideUnchangedRegions.enabled');
                const openOptions = {
                    ...(0, converter_1.viewColumnToResourceOpenOptions)(options === null || options === void 0 ? void 0 : options.viewColumn),
                    revealFirstDiff: true,
                    ...options,
                };
                return this.commandService.executeCommand(ide_core_browser_1.EDITOR_COMMANDS.COMPARE.id, {
                    original: ide_core_browser_1.URI.from(left),
                    modified: ide_core_browser_1.URI.from(right),
                    name: title,
                }, openOptions);
            },
        });
        registry.registerCommand({
            id: VSCodeBuiltinCommands.WALKTHROUGHS_COMMAND_GET_STARTED.id,
            category: (0, ide_core_browser_1.localize)('walkthroughs.welcome'),
            label: (0, ide_core_browser_1.localize)('walkthroughs.get.started'),
        }, {
            execute: async (extensionId) => {
                const allWalkthrough = this.walkthroughsService.getWalkthroughs();
                if (extensionId) {
                    this.walkthroughsService.openWalkthroughEditor(extensionId);
                }
                else {
                    const result = await this.quickPickService.show(allWalkthrough.map((w) => ({
                        label: w.title,
                        value: w.id,
                        description: w.source,
                        detail: w.description,
                    })));
                    if (result) {
                        this.walkthroughsService.openWalkthroughEditor(result);
                    }
                }
            },
        });
        [
            // layout builtin commands
            VSCodeBuiltinCommands.LAYOUT_COMMAND_MAXIMIZE_EDITOR,
            // editor builtin commands
            VSCodeBuiltinCommands.WORKBENCH_CLOSE_ACTIVE_EDITOR,
            VSCodeBuiltinCommands.REVERT_AND_CLOSE_ACTIVE_EDITOR,
            VSCodeBuiltinCommands.SPLIT_EDITOR_RIGHT,
            VSCodeBuiltinCommands.SPLIT_EDITOR_DOWN,
            VSCodeBuiltinCommands.EDITOR_NAVIGATE_BACK,
            VSCodeBuiltinCommands.EDITOR_NAVIGATE_FORWARD,
            VSCodeBuiltinCommands.EDITOR_SAVE_ALL,
            VSCodeBuiltinCommands.CLOSE_ALL_EDITORS,
            VSCodeBuiltinCommands.PREVIOUS_EDITOR,
            VSCodeBuiltinCommands.PREVIOUS_EDITOR_IN_GROUP,
            VSCodeBuiltinCommands.NEXT_EDITOR,
            VSCodeBuiltinCommands.NEXT_EDITOR_IN_GROUP,
            VSCodeBuiltinCommands.EVEN_EDITOR_WIDTH,
            VSCodeBuiltinCommands.CLOSE_OTHER_GROUPS,
            VSCodeBuiltinCommands.CLOSE_UNMODIFIED_EDITORS,
            VSCodeBuiltinCommands.LAST_EDITOR_IN_GROUP,
            VSCodeBuiltinCommands.OPEN_EDITOR_AT_INDEX,
            VSCodeBuiltinCommands.CLOSE_OTHER_EDITORS,
            VSCodeBuiltinCommands.NEW_UNTITLED_FILE,
            VSCodeBuiltinCommands.FILE_SAVE,
            VSCodeBuiltinCommands.SPLIT_EDITOR,
            VSCodeBuiltinCommands.SPLIT_EDITOR_ORTHOGONAL,
            VSCodeBuiltinCommands.NAVIGATE_LEFT,
            VSCodeBuiltinCommands.NAVIGATE_RIGHT,
            VSCodeBuiltinCommands.NAVIGATE_UP,
            VSCodeBuiltinCommands.NAVIGATE_DOWN,
            VSCodeBuiltinCommands.NAVIGATE_NEXT,
            VSCodeBuiltinCommands.REVERT_FILES,
            VSCodeBuiltinCommands.WORKBENCH_FOCUS_FILES_EXPLORER,
            VSCodeBuiltinCommands.WORKBENCH_FOCUS_ACTIVE_EDITOR_GROUP,
            VSCodeBuiltinCommands.API_OPEN_EDITOR_COMMAND_ID,
            VSCodeBuiltinCommands.API_OPEN_DIFF_EDITOR_COMMAND_ID,
            VSCodeBuiltinCommands.API_OPEN_WITH_EDITOR_COMMAND_ID,
            // debug builtin commands
            VSCodeBuiltinCommands.DEBUG_START,
            VSCodeBuiltinCommands.DEBUG_ADD,
            VSCodeBuiltinCommands.DEBUG_COMMAND_STEP_INTO,
            VSCodeBuiltinCommands.DEBUG_COMMAND_STEP_OVER,
            VSCodeBuiltinCommands.DEBUG_COMMAND_STEP_OUT,
            VSCodeBuiltinCommands.DEBUG_COMMAND_CONTINUE,
            VSCodeBuiltinCommands.DEBUG_COMMAND_RUN,
            VSCodeBuiltinCommands.DEBUG_COMMAND_START,
            VSCodeBuiltinCommands.DEBUG_COMMAND_PAUSE,
            VSCodeBuiltinCommands.DEBUG_COMMAND_RESTART,
            VSCodeBuiltinCommands.DEBUG_COMMAND_STOP,
            VSCodeBuiltinCommands.EDITOR_SHOW_ALL_SYMBOLS,
            // search builtin commands
            VSCodeBuiltinCommands.SEARCH_COMMAND_OPEN_SEARCH,
            // explorer builtin commands
            VSCodeBuiltinCommands.REVEAL_IN_EXPLORER,
            VSCodeBuiltinCommands.OPEN_FOLDER,
            VSCodeBuiltinCommands.SIDEBAR_TOGGLE_VISIBILITY,
            // terminal builtin commands
            VSCodeBuiltinCommands.CLEAR_TERMINAL,
            VSCodeBuiltinCommands.TERMINAL_COMMAND_FOCUS,
            VSCodeBuiltinCommands.TERMINAL_COMMAND_TOGGLE_VISIBILITY,
            VSCodeBuiltinCommands.NEW_WORKBENCH_VIEW_TERMINAL,
            // file builtin commmands
            VSCodeBuiltinCommands.FILE_COMMAND_RENAME_FILE,
            // marker builtin commands
            VSCodeBuiltinCommands.MARKER_COMMAND_SHOW_ERRORS_WARNINGS,
            VSCodeBuiltinCommands.MARKER_COMMAND_TOGGLE_SHOW_ERRORS_WARNINGS,
            // others
            VSCodeBuiltinCommands.RELOAD_WINDOW,
            VSCodeBuiltinCommands.SETTINGS_COMMAND_OPEN_SETTINGS,
            VSCodeBuiltinCommands.SETTINGS_COMMAND_OPEN_GLOBAL_SETTINGS,
            VSCodeBuiltinCommands.SETTINGS_COMMAND_OPEN_SETTINGS_JSON,
            VSCodeBuiltinCommands.SETTINGS_COMMAND_OPEN_GLOBAL_OPEN_KEYMAPS,
            VSCodeBuiltinCommands.THEME_COMMAND_QUICK_SELECT,
            // merge editor
            VSCodeBuiltinCommands.OPEN_MERGEEDITOR,
        ].forEach((command) => {
            registry.registerCommand(command);
        });
    }
    doOpenWith(uri, columnAndOptions, label, forceOpenType) {
        const [columnArg, optionsArg] = columnAndOptions !== null && columnAndOptions !== void 0 ? columnAndOptions : [];
        const options = {};
        if (typeof columnArg === 'number') {
            options.groupIndex = columnArg;
        }
        if (optionsArg) {
            options.focus = options.preserveFocus = optionsArg.preserveFocus;
            // 这个range 可能是 vscode.range， 因为不会经过args转换
            if (optionsArg.selection && (0, converter_1.isLikelyVscodeRange)(optionsArg.selection)) {
                optionsArg.selection = (0, converter_1.fromRange)(optionsArg.selection);
            }
            if (Array.isArray(optionsArg.selection) && optionsArg.selection.length === 2) {
                const [start, end] = optionsArg.selection;
                options.range = {
                    startLineNumber: start.line + 1,
                    startColumn: start.character + 1,
                    endLineNumber: end.line + 1,
                    endColumn: end.character + 1,
                };
            }
            else {
                options.range = optionsArg.selection;
            }
            options.preview = optionsArg.preview;
        }
        if (forceOpenType) {
            options.forceOpenType = forceOpenType;
        }
        if (label) {
            options.label = label;
        }
        return this.workbenchEditorService.open(uri, options);
    }
    asQuickOpenItems(activated) {
        const nodes = activated.node ? activated.node.map((e, i) => this.toQuickOpenItem(e, 'Node.js', i === 0)) : [];
        const workers = activated.worker
            ? activated.worker.map((e, i) => this.toQuickOpenItem(e, 'Web Worker', i === 0))
            : [];
        return [...nodes, ...workers];
    }
    toQuickOpenItem(e, host, firstItem) {
        const extension = this.extensionInstanceManageService.getExtensionInstanceByExtId(e.id);
        return new ide_core_browser_1.QuickOpenItem({
            groupLabel: firstItem ? host : undefined,
            showBorder: !!firstItem,
            label: (0, ide_core_browser_1.replaceLocalizePlaceholder)(e.displayName, e.id),
            description: (0, ide_core_browser_1.replaceLocalizePlaceholder)(e.description, e.id),
            detail: extension === null || extension === void 0 ? void 0 : extension.realPath,
        });
    }
    /**
     * 当前客户端 id
     */
    get clientId() {
        return (0, exports.getClientId)(this.injector);
    }
};
exports.ExtensionCommandContribution = ExtensionCommandContribution;
tslib_1.__decorate([
    (0, di_1.Autowired)(di_1.INJECTOR_TOKEN),
    tslib_1.__metadata("design:type", di_1.Injector)
], ExtensionCommandContribution.prototype, "injector", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_editor_1.WorkbenchEditorService),
    tslib_1.__metadata("design:type", ide_editor_1.WorkbenchEditorService)
], ExtensionCommandContribution.prototype, "workbenchEditorService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(types_1.IActivationEventService),
    tslib_1.__metadata("design:type", types_1.IActivationEventService)
], ExtensionCommandContribution.prototype, "activationEventService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.QuickOpenService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "quickOpenService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.QuickPickService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "quickPickService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionHostProfilerServicePath),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "extensionProfiler", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(status_bar_service_1.IStatusBarService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "statusBar", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_overlay_1.IWindowDialogService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "dialogService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IClientApp),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "clientApp", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IEventBus),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "eventBus", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.CommandService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "commandService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.IContextKeyService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "contextKeyService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_webview_1.IWebviewService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "webviewService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(common_1.ExtensionService),
    tslib_1.__metadata("design:type", common_1.ExtensionService)
], ExtensionCommandContribution.prototype, "extensionService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(types_1.AbstractExtInstanceManagementService),
    tslib_1.__metadata("design:type", types_1.AbstractExtInstanceManagementService)
], ExtensionCommandContribution.prototype, "extensionInstanceManageService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(walkthroughs_service_1.WalkthroughsService),
    tslib_1.__metadata("design:type", walkthroughs_service_1.WalkthroughsService)
], ExtensionCommandContribution.prototype, "walkthroughsService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.PreferenceService),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "preferenceService", void 0);
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_browser_1.ILogger),
    tslib_1.__metadata("design:type", Object)
], ExtensionCommandContribution.prototype, "logger", void 0);
exports.ExtensionCommandContribution = ExtensionCommandContribution = tslib_1.__decorate([
    (0, ide_core_browser_1.Domain)(ide_core_browser_1.CommandContribution)
], ExtensionCommandContribution);
//# sourceMappingURL=extension.contribution.js.map