"use strict";
/** ******************************************************************************
 * Copyright (C) 2018 Red Hat, Inc. and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/
// Some code copied and modified from https://github.com/eclipse-theia/theia/tree/v1.14.0/packages/plugin-ext/src/plugin/scm.ts
var _ExtHostSCMInputBox_proxy, _ExtHostSCMInputBox_commands, _ExtHostSourceControlResourceGroup_proxy, _ExtHostSourceControl_proxy;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExtHostSCM = exports.ExtHostSCMInputBox = void 0;
const tslib_1 = require("tslib");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const vscode_1 = require("../../../common/vscode");
const { sortedDiff } = ide_core_common_1.arrays;
function getIconPath(decorations) {
    if (!decorations) {
        return undefined;
    }
    else if (typeof decorations.iconPath === 'string') {
        return ide_core_common_1.Uri.file(decorations.iconPath).toString();
    }
    else if (decorations.iconPath) {
        return `${decorations.iconPath}`;
    }
    return undefined;
}
function compareResourceThemableDecorations(a, b) {
    if (!a.iconPath && !b.iconPath) {
        return 0;
    }
    else if (!a.iconPath) {
        return -1;
    }
    else if (!b.iconPath) {
        return 1;
    }
    const aPath = typeof a.iconPath === 'string' ? a.iconPath : a.iconPath.fsPath;
    const bPath = typeof b.iconPath === 'string' ? b.iconPath : b.iconPath.fsPath;
    return (0, ide_core_common_1.comparePaths)(aPath, bPath);
}
function compareResourceStatesDecorations(a, b) {
    let result = 0;
    if (a.strikeThrough !== b.strikeThrough) {
        return a.strikeThrough ? 1 : -1;
    }
    if (a.faded !== b.faded) {
        return a.faded ? 1 : -1;
    }
    if (a.tooltip !== b.tooltip) {
        return (a.tooltip || '').localeCompare(b.tooltip || '');
    }
    result = compareResourceThemableDecorations(a, b);
    if (result !== 0) {
        return result;
    }
    if (a.light && b.light) {
        result = compareResourceThemableDecorations(a.light, b.light);
    }
    else if (a.light) {
        return 1;
    }
    else if (b.light) {
        return -1;
    }
    if (result !== 0) {
        return result;
    }
    if (a.dark && b.dark) {
        result = compareResourceThemableDecorations(a.dark, b.dark);
    }
    else if (a.dark) {
        return 1;
    }
    else if (b.dark) {
        return -1;
    }
    return result;
}
function compareResourceStates(a, b) {
    let result = (0, ide_core_common_1.comparePaths)(a.resourceUri.fsPath, b.resourceUri.fsPath, true);
    if (result !== 0) {
        return result;
    }
    if (a.decorations && b.decorations) {
        result = compareResourceStatesDecorations(a.decorations, b.decorations);
    }
    else if (a.decorations) {
        return 1;
    }
    else if (b.decorations) {
        return -1;
    }
    return result;
}
function compareArgs(a, b) {
    for (let i = 0; i < a.length; i++) {
        if (a[i] !== b[i]) {
            return false;
        }
    }
    return true;
}
function commandEquals(a, b) {
    return (a.command === b.command &&
        a.title === b.title &&
        a.tooltip === b.tooltip &&
        (a.arguments && b.arguments ? compareArgs(a.arguments, b.arguments) : a.arguments === b.arguments));
}
function commandListEquals(a, b) {
    if (a.length !== b.length) {
        return false;
    }
    for (let i = 0; i < a.length; i++) {
        if (!commandEquals(a[i], b[i])) {
            return false;
        }
    }
    return true;
}
function historyItemGroupEquals(a, b) {
    var _a, _b, _c, _d;
    if (a === b) {
        return true;
    }
    if (!a || !b) {
        return false;
    }
    return (a.id === b.id && a.label === b.label && ((_a = a.upstream) === null || _a === void 0 ? void 0 : _a.id) === ((_b = b.upstream) === null || _b === void 0 ? void 0 : _b.id) && ((_c = a.upstream) === null || _c === void 0 ? void 0 : _c.label) === ((_d = b.upstream) === null || _d === void 0 ? void 0 : _d.label));
}
function getInputBoxActionButtonIcon(actionButton) {
    if (!(actionButton === null || actionButton === void 0 ? void 0 : actionButton.icon)) {
        return undefined;
    }
    else if (ide_core_common_1.Uri.isUri(actionButton.icon)) {
        return actionButton.icon;
    }
    else {
        const icon = actionButton.icon;
        return { light: icon.light, dark: icon.dark };
    }
}
class ExtHostSCMInputBox {
    get value() {
        return this._value;
    }
    set value(value) {
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setInputBoxValue(this._sourceControlHandle, value);
        this.updateValue(value);
    }
    get enabled() {
        return this._enabled;
    }
    set enabled(enabled) {
        enabled = !!enabled;
        if (this._enabled === enabled) {
            return;
        }
        this._enabled = enabled;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setInputBoxEnablement(this._sourceControlHandle, enabled);
    }
    get onDidChange() {
        return this._onDidChange.event;
    }
    get placeholder() {
        return this._placeholder;
    }
    set placeholder(placeholder) {
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setInputBoxPlaceholder(this._sourceControlHandle, placeholder);
        this._placeholder = placeholder;
    }
    get validateInput() {
        return this._validateInput;
    }
    set validateInput(fn) {
        if (fn && typeof fn !== 'function') {
            (0, ide_core_common_1.getDebugLogger)().warn('Invalid SCM input box validation function');
            return;
        }
        this._validateInput = fn;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setValidationProviderIsEnabled(this._sourceControlHandle, !!fn);
    }
    get visible() {
        return this._visible;
    }
    set visible(visible) {
        visible = !!visible;
        this._visible = visible;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setInputBoxVisibility(this._sourceControlHandle, visible);
    }
    get actionButton() {
        return this._actionButton;
    }
    set actionButton(actionButton) {
        this._actionButtonDisposables.value = new ide_core_common_1.DisposableStore();
        this._actionButton = actionButton;
        const internal = actionButton !== undefined
            ? {
                command: tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_commands, "f").converter.toInternal(actionButton.command, this._actionButtonDisposables.value),
                icon: getInputBoxActionButtonIcon(actionButton),
                enabled: actionButton.enabled,
            }
            : undefined;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSCMInputBox_proxy, "f").$setInputBoxActionButton(this._sourceControlHandle, internal !== null && internal !== void 0 ? internal : null);
    }
    constructor(_extension, _proxy, _sourceControlHandle, _commands) {
        this._extension = _extension;
        this._sourceControlHandle = _sourceControlHandle;
        _ExtHostSCMInputBox_proxy.set(this, void 0);
        _ExtHostSCMInputBox_commands.set(this, void 0);
        this._value = '';
        this._enabled = true;
        this._onDidChange = new ide_core_common_1.Emitter();
        this._placeholder = '';
        this._visible = true;
        this._actionButtonDisposables = new ide_core_common_1.MutableDisposable();
        tslib_1.__classPrivateFieldSet(this, _ExtHostSCMInputBox_proxy, _proxy, "f");
        tslib_1.__classPrivateFieldSet(this, _ExtHostSCMInputBox_commands, _commands, "f");
    }
    $onInputBoxValueChange(value) {
        this.updateValue(value);
    }
    updateValue(value) {
        this._value = value;
        this._onDidChange.fire(value);
    }
}
exports.ExtHostSCMInputBox = ExtHostSCMInputBox;
_ExtHostSCMInputBox_proxy = new WeakMap(), _ExtHostSCMInputBox_commands = new WeakMap();
class ExtHostSourceControlResourceGroup {
    get id() {
        return this._id;
    }
    get label() {
        return this._label;
    }
    set label(label) {
        this._label = label;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControlResourceGroup_proxy, "f").$updateGroupLabel(this._sourceControlHandle, this.handle, label);
    }
    get hideWhenEmpty() {
        return this._hideWhenEmpty;
    }
    set hideWhenEmpty(hideWhenEmpty) {
        this._hideWhenEmpty = hideWhenEmpty;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControlResourceGroup_proxy, "f").$updateGroup(this._sourceControlHandle, this.handle, { hideWhenEmpty });
    }
    get resourceStates() {
        return [...this._resourceStates];
    }
    set resourceStates(resources) {
        this._resourceStates = [...resources];
        this._onDidUpdateResourceStates.fire();
    }
    constructor(_proxy, _commands, _sourceControlHandle, _id, _label) {
        this._commands = _commands;
        this._sourceControlHandle = _sourceControlHandle;
        this._id = _id;
        this._label = _label;
        this._resourceHandlePool = 0;
        this._resourceStates = [];
        this._resourceStatesMap = new Map();
        this._resourceStatesCommandsMap = new Map();
        this._resourceStatesDisposablesMap = new Map();
        this._onDidUpdateResourceStates = new ide_core_common_1.Emitter();
        this.onDidUpdateResourceStates = this._onDidUpdateResourceStates.event;
        this._onDidDispose = new ide_core_common_1.Emitter();
        this.onDidDispose = this._onDidDispose.event;
        this._handlesSnapshot = [];
        this._resourceSnapshot = [];
        this._hideWhenEmpty = undefined;
        this.handle = ExtHostSourceControlResourceGroup._handlePool++;
        _ExtHostSourceControlResourceGroup_proxy.set(this, void 0);
        tslib_1.__classPrivateFieldSet(this, _ExtHostSourceControlResourceGroup_proxy, _proxy, "f");
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControlResourceGroup_proxy, "f").$registerGroup(_sourceControlHandle, this.handle, _id, _label);
    }
    getResourceState(handle) {
        return this._resourceStatesMap.get(handle);
    }
    $executeResourceCommand(handle, preserveFocus) {
        const command = this._resourceStatesCommandsMap.get(handle);
        if (!command) {
            return Promise.resolve(undefined);
        }
        return (0, ide_core_common_1.asPromise)(() => this._commands.executeCommand(command.command, ...(command.arguments || []), preserveFocus));
    }
    _takeResourceStateSnapshot() {
        const snapshot = [...this._resourceStates].sort(compareResourceStates);
        const diffs = sortedDiff(this._resourceSnapshot, snapshot, compareResourceStates);
        const splices = diffs.map((diff) => {
            const toInsert = diff.toInsert.map((r) => {
                const handle = this._resourceHandlePool++;
                this._resourceStatesMap.set(handle, r);
                const sourceUri = r.resourceUri;
                const iconPath = getIconPath(r.decorations);
                const lightIconPath = (r.decorations && getIconPath(r.decorations.light)) || iconPath;
                const darkIconPath = (r.decorations && getIconPath(r.decorations.dark)) || iconPath;
                const icons = [];
                let command;
                if (r.command) {
                    if (r.command.command === 'vscode.open' || r.command.command === 'vscode.diff') {
                        const disposables = new ide_core_common_1.DisposableStore();
                        command = this._commands.converter.toInternal(r.command, disposables);
                        this._resourceStatesDisposablesMap.set(handle, disposables);
                    }
                    else {
                        this._resourceStatesCommandsMap.set(handle, r.command);
                    }
                }
                if (lightIconPath) {
                    icons.push(lightIconPath);
                }
                if (darkIconPath && darkIconPath !== lightIconPath) {
                    icons.push(darkIconPath);
                }
                const tooltip = (r.decorations && r.decorations.tooltip) || '';
                const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
                const faded = r.decorations && !!r.decorations.faded;
                const contextValue = r.contextValue || '';
                const rawResource = [
                    handle,
                    sourceUri,
                    icons,
                    tooltip,
                    strikeThrough,
                    faded,
                    contextValue,
                    command,
                ];
                return { rawResource, handle };
            });
            return { start: diff.start, deleteCount: diff.deleteCount, toInsert };
        });
        const rawResourceSplices = splices.map(({ start, deleteCount, toInsert }) => [start, deleteCount, toInsert.map((i) => i.rawResource)]);
        const reverseSplices = splices.reverse();
        for (const { start, deleteCount, toInsert } of reverseSplices) {
            const handles = toInsert.map((i) => i.handle);
            const handlesToDelete = this._handlesSnapshot.splice(start, deleteCount, ...handles);
            for (const handle of handlesToDelete) {
                this._resourceStatesMap.delete(handle);
                this._resourceStatesCommandsMap.delete(handle);
            }
        }
        this._resourceSnapshot = snapshot;
        return rawResourceSplices;
    }
    dispose() {
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControlResourceGroup_proxy, "f").$unregisterGroup(this._sourceControlHandle, this.handle);
        this._onDidDispose.fire();
    }
}
_ExtHostSourceControlResourceGroup_proxy = new WeakMap();
ExtHostSourceControlResourceGroup._handlePool = 0;
class ExtHostSourceControl {
    get actionButton() {
        return this._actionButton;
    }
    set actionButton(actionButton) {
        var _a, _b, _c;
        this._actionButtonDisposables.value = new ide_core_common_1.DisposableStore();
        this._actionButton = actionButton;
        /**
         * 仅适配 Git 1.62.3 版本逻辑，该版本下 actionButton 为单个按钮，返回数据结构如下：
         * {
         *   arguments: [ExtHostSourceControl]
         *   command: "git.publish"
         *   title: "$(cloud-upload) Publish Changes"
         *   tooltip: "Publish Changes"
         * }
         * 通过是判断 command 类型进行区分
         */
        let internal;
        if ((0, ide_core_common_1.isUndefined)(actionButton)) {
            internal = undefined;
        }
        else if (typeof (actionButton === null || actionButton === void 0 ? void 0 : actionButton.command) === 'string') {
            internal = {
                command: this._commands.converter.toInternal(actionButton, this._actionButtonDisposables.value),
                secondaryCommands: (_a = actionButton.secondaryCommands) === null || _a === void 0 ? void 0 : _a.map((commandGroup) => commandGroup.map((command) => this._commands.converter.toInternal(command, this._actionButtonDisposables.value))),
                description: actionButton.title,
                enabled: true,
            };
        }
        else {
            internal = {
                command: this._commands.converter.toInternal(actionButton.command, this._actionButtonDisposables.value),
                secondaryCommands: (_b = actionButton.secondaryCommands) === null || _b === void 0 ? void 0 : _b.map((commandGroup) => commandGroup.map((command) => this._commands.converter.toInternal(command, this._actionButtonDisposables.value))),
                description: actionButton.description || actionButton.tooltip,
                enabled: (_c = actionButton.enabled) !== null && _c !== void 0 ? _c : true,
            };
        }
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { actionButton: internal !== null && internal !== void 0 ? internal : null });
    }
    get id() {
        return this._id;
    }
    get label() {
        return this._label;
    }
    get rootUri() {
        return this._rootUri;
    }
    get inputBox() {
        return this._inputBox;
    }
    get count() {
        return this._count;
    }
    set count(count) {
        if (this._count === count) {
            return;
        }
        this._count = count;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { count });
    }
    get quickDiffProvider() {
        return this._quickDiffProvider;
    }
    set quickDiffProvider(quickDiffProvider) {
        this._quickDiffProvider = quickDiffProvider;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { hasQuickDiffProvider: !!quickDiffProvider });
    }
    get historyProvider() {
        return this._historyProvider;
    }
    set historyProvider(historyProvider) {
        this._historyProvider = historyProvider;
        this._historyProviderDisposable.value = new ide_core_common_1.DisposableStore();
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { hasHistoryProvider: !!historyProvider });
        if (historyProvider) {
            this._historyProviderDisposable.value.add(historyProvider.onDidChangeCurrentHistoryItemGroup(() => {
                if (historyItemGroupEquals(this._historyProviderCurrentHistoryItemGroup, historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.currentHistoryItemGroup)) {
                    return;
                }
                this._historyProviderCurrentHistoryItemGroup = historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.currentHistoryItemGroup;
                tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$onDidChangeHistoryProviderCurrentHistoryItemGroup(this.handle, this._historyProviderCurrentHistoryItemGroup);
            }));
            if (historyProvider.onDidChangeActionButton) {
                this._historyProviderDisposable.value.add(historyProvider.onDidChangeActionButton(() => {
                    this._historyProviderActionButtonDisposable.value = new ide_core_common_1.DisposableStore();
                    const internal = historyProvider.actionButton !== undefined
                        ? {
                            command: this._commands.converter.toInternal(historyProvider.actionButton.command, this._historyProviderActionButtonDisposable.value),
                            description: historyProvider.actionButton.description,
                            enabled: historyProvider.actionButton.enabled,
                        }
                        : undefined;
                    tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$onDidChangeHistoryProviderActionButton(this.handle, internal !== null && internal !== void 0 ? internal : null);
                }));
            }
        }
    }
    get commitTemplate() {
        return this._commitTemplate;
    }
    set commitTemplate(commitTemplate) {
        this._commitTemplate = commitTemplate;
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { commitTemplate });
    }
    get acceptInputCommand() {
        return this._acceptInputCommand;
    }
    set acceptInputCommand(acceptInputCommand) {
        this._acceptInputDisposables.value = new ide_core_common_1.DisposableStore();
        this._acceptInputCommand = acceptInputCommand;
        const internal = this._commands.converter.toInternal(acceptInputCommand, this._acceptInputDisposables.value);
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { acceptInputCommand: internal });
    }
    get statusBarCommands() {
        return this._statusBarCommands;
    }
    set statusBarCommands(statusBarCommands) {
        if (this._statusBarCommands && statusBarCommands && commandListEquals(this._statusBarCommands, statusBarCommands)) {
            return;
        }
        this._statusBarDisposables.value = new ide_core_common_1.DisposableStore();
        this._statusBarCommands = statusBarCommands;
        const internal = (statusBarCommands || []).map((c) => this._commands.converter.toInternal(c, this._statusBarDisposables.value));
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$updateSourceControl(this.handle, { statusBarCommands: internal });
    }
    get selected() {
        return this._selected;
    }
    constructor(_extension, _proxy, _commands, _id, _label, _rootUri) {
        this._commands = _commands;
        this._id = _id;
        this._label = _label;
        this._rootUri = _rootUri;
        this._groups = new Map();
        this._actionButtonDisposables = new ide_core_common_1.MutableDisposable();
        this._count = undefined;
        this._quickDiffProvider = undefined;
        this._historyProviderDisposable = new ide_core_common_1.MutableDisposable();
        this._historyProviderActionButtonDisposable = new ide_core_common_1.MutableDisposable();
        this._commitTemplate = undefined;
        this._acceptInputDisposables = new ide_core_common_1.MutableDisposable();
        this._acceptInputCommand = undefined;
        this._statusBarDisposables = new ide_core_common_1.MutableDisposable();
        this._statusBarCommands = undefined;
        this._selected = false;
        this._onDidChangeSelection = new ide_core_common_1.Emitter();
        this.onDidChangeSelection = this._onDidChangeSelection.event;
        this.handle = ExtHostSourceControl._handlePool++;
        _ExtHostSourceControl_proxy.set(this, void 0);
        this.updatedResourceGroups = new Set();
        tslib_1.__classPrivateFieldSet(this, _ExtHostSourceControl_proxy, _proxy, "f");
        this._inputBox = new ExtHostSCMInputBox(_extension, tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f"), this.handle, this._commands);
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$registerSourceControl(this.handle, _id, _label, _rootUri);
    }
    createResourceGroup(id, label) {
        const group = new ExtHostSourceControlResourceGroup(tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f"), this._commands, this.handle, id, label);
        const updateListener = group.onDidUpdateResourceStates(() => {
            this.updatedResourceGroups.add(group);
            this.eventuallyUpdateResourceStates();
        });
        ide_core_common_1.Event.once(group.onDidDispose)(() => {
            this.updatedResourceGroups.delete(group);
            updateListener.dispose();
            this._groups.delete(group.handle);
        });
        this._groups.set(group.handle, group);
        return group;
    }
    eventuallyUpdateResourceStates() {
        const splices = [];
        this.updatedResourceGroups.forEach((group) => {
            const snapshot = group._takeResourceStateSnapshot();
            if (snapshot.length === 0) {
                return;
            }
            splices.push([group.handle, snapshot]);
        });
        if (splices.length > 0) {
            tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$spliceResourceStates(this.handle, splices);
        }
        this.updatedResourceGroups.clear();
    }
    getResourceGroup(handle) {
        return this._groups.get(handle);
    }
    setSelectionState(selected) {
        this._selected = selected;
        this._onDidChangeSelection.fire(selected);
    }
    dispose() {
        this._acceptInputDisposables.dispose();
        this._statusBarDisposables.dispose();
        this._groups.forEach((group) => group.dispose());
        tslib_1.__classPrivateFieldGet(this, _ExtHostSourceControl_proxy, "f").$unregisterSourceControl(this.handle);
    }
}
_ExtHostSourceControl_proxy = new WeakMap();
ExtHostSourceControl._handlePool = 0;
tslib_1.__decorate([
    (0, ide_core_common_1.debounce)(100),
    tslib_1.__metadata("design:type", Function),
    tslib_1.__metadata("design:paramtypes", []),
    tslib_1.__metadata("design:returntype", void 0)
], ExtHostSourceControl.prototype, "eventuallyUpdateResourceStates", null);
class ExtHostSCM {
    get onDidChangeActiveProvider() {
        return this._onDidChangeActiveProvider.event;
    }
    constructor(rpc, _commands) {
        this._commands = _commands;
        this.logger = (0, ide_core_common_1.getDebugLogger)();
        this._sourceControls = new Map();
        this._sourceControlsByExtension = new Map();
        this._onDidChangeActiveProvider = new ide_core_common_1.Emitter();
        this._selectedSourceControlHandles = new Set();
        this._proxy = rpc.getProxy(vscode_1.MainThreadAPIIdentifier.MainThreadSCM);
        _commands.registerArgumentProcessor({
            processArgument: (arg) => {
                if (arg && arg.$mid === 3) {
                    const sourceControl = this._sourceControls.get(arg.sourceControlHandle);
                    if (!sourceControl) {
                        return arg;
                    }
                    const group = sourceControl.getResourceGroup(arg.groupHandle);
                    if (!group) {
                        return arg;
                    }
                    return group.getResourceState(arg.handle);
                }
                else if (arg && arg.$mid === 4) {
                    const sourceControl = this._sourceControls.get(arg.sourceControlHandle);
                    if (!sourceControl) {
                        return arg;
                    }
                    return sourceControl.getResourceGroup(arg.groupHandle);
                }
                else if (arg && arg.$mid === 5) {
                    const sourceControl = this._sourceControls.get(arg.handle);
                    if (!sourceControl) {
                        return arg;
                    }
                    return sourceControl;
                }
                return arg;
            },
        });
    }
    getSourceControl(extensionId, id) {
        this.logger.log('ExtHostSCM#$getSourceControl', extensionId, id);
        const sourceControls = this._sourceControlsByExtension.get(extensionId) || [];
        return sourceControls.filter((source) => source.id === id);
    }
    createSourceControl(extension, id, label, rootUri) {
        this.logger.log('ExtHostSCM#createSourceControl', extension.id, id, label, rootUri);
        const handle = ExtHostSCM._handlePool++;
        const sourceControl = new ExtHostSourceControl(extension, this._proxy, this._commands, id, label, rootUri);
        this._sourceControls.set(handle, sourceControl);
        const sourceControls = this._sourceControlsByExtension.get(extension.id) || [];
        sourceControls.push(sourceControl);
        this._sourceControlsByExtension.set(extension.id, sourceControls);
        return sourceControl;
    }
    // Deprecated
    getLastInputBox(extension) {
        this.logger.log('ExtHostSCM#getLastInputBox', extension.id);
        const sourceControls = this._sourceControlsByExtension.get(extension.id);
        const sourceControl = sourceControls && sourceControls[sourceControls.length - 1];
        return sourceControl && sourceControl.inputBox;
    }
    $provideOriginalResource(sourceControlHandle, uriComponents, token) {
        const uri = ide_core_common_1.Uri.revive(uriComponents);
        this.logger.log('ExtHostSCM#$provideOriginalResource', sourceControlHandle, uri.toString());
        const sourceControl = this._sourceControls.get(sourceControlHandle);
        if (!sourceControl ||
            !sourceControl.quickDiffProvider ||
            !sourceControl.quickDiffProvider.provideOriginalResource) {
            return Promise.resolve(null);
        }
        return (0, ide_core_common_1.asPromise)(() => sourceControl.quickDiffProvider.provideOriginalResource(uri, token)).then((r) => r || null);
    }
    $onInputBoxValueChange(sourceControlHandle, value) {
        this.logger.log('ExtHostSCM#$onInputBoxValueChange', sourceControlHandle);
        const sourceControl = this._sourceControls.get(sourceControlHandle);
        if (!sourceControl) {
            return Promise.resolve(undefined);
        }
        sourceControl.inputBox.$onInputBoxValueChange(value);
        return Promise.resolve(undefined);
    }
    $executeResourceCommand(sourceControlHandle, groupHandle, handle, preserveFocus) {
        this.logger.log('ExtHostSCM#$executeResourceCommand', sourceControlHandle, groupHandle, handle);
        const sourceControl = this._sourceControls.get(sourceControlHandle);
        if (!sourceControl) {
            return Promise.resolve(undefined);
        }
        const group = sourceControl.getResourceGroup(groupHandle);
        if (!group) {
            return Promise.resolve(undefined);
        }
        return group.$executeResourceCommand(handle, preserveFocus);
    }
    $validateInput(sourceControlHandle, value, cursorPosition) {
        this.logger.log('ExtHostSCM#$validateInput', sourceControlHandle);
        const sourceControl = this._sourceControls.get(sourceControlHandle);
        if (!sourceControl) {
            return Promise.resolve(undefined);
        }
        if (!sourceControl.inputBox.validateInput) {
            return Promise.resolve(undefined);
        }
        return (0, ide_core_common_1.asPromise)(() => sourceControl.inputBox.validateInput(value, cursorPosition)).then((result) => {
            if (!result) {
                return Promise.resolve(undefined);
            }
            return Promise.resolve([result.message.toString(), result.type]);
        });
    }
    $setSelectedSourceControls(selectedSourceControlHandles) {
        this.logger.log('ExtHostSCM#$setSelectedSourceControls', selectedSourceControlHandles);
        const set = new Set();
        for (const handle of selectedSourceControlHandles) {
            set.add(handle);
        }
        set.forEach((handle) => {
            if (!this._selectedSourceControlHandles.has(handle)) {
                const sourceControl = this._sourceControls.get(handle);
                if (!sourceControl) {
                    return;
                }
                sourceControl.setSelectionState(true);
            }
        });
        this._selectedSourceControlHandles.forEach((handle) => {
            if (!set.has(handle)) {
                const sourceControl = this._sourceControls.get(handle);
                if (!sourceControl) {
                    return;
                }
                sourceControl.setSelectionState(false);
            }
        });
        this._selectedSourceControlHandles = set;
        return Promise.resolve(undefined);
    }
    async $resolveHistoryItemGroupBase(sourceControlHandle, historyItemGroupId, token) {
        var _a, _b;
        const historyProvider = (_a = this._sourceControls.get(sourceControlHandle)) === null || _a === void 0 ? void 0 : _a.historyProvider;
        return (_b = (await (historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.resolveHistoryItemGroupBase(historyItemGroupId, token)))) !== null && _b !== void 0 ? _b : undefined;
    }
    async $resolveHistoryItemGroupCommonAncestor(sourceControlHandle, historyItemGroupId1, historyItemGroupId2, token) {
        var _a, _b;
        const historyProvider = (_a = this._sourceControls.get(sourceControlHandle)) === null || _a === void 0 ? void 0 : _a.historyProvider;
        return ((_b = (await (historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.resolveHistoryItemGroupCommonAncestor(historyItemGroupId1, historyItemGroupId2, token)))) !== null && _b !== void 0 ? _b : undefined);
    }
    async $provideHistoryItems(sourceControlHandle, historyItemGroupId, options, token) {
        var _a;
        const historyProvider = (_a = this._sourceControls.get(sourceControlHandle)) === null || _a === void 0 ? void 0 : _a.historyProvider;
        const historyItems = await (historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.provideHistoryItems(historyItemGroupId, options, token));
        return historyItems !== null && historyItems !== void 0 ? historyItems : undefined;
    }
    async $provideHistoryItemChanges(sourceControlHandle, historyItemId, token) {
        var _a, _b;
        const historyProvider = (_a = this._sourceControls.get(sourceControlHandle)) === null || _a === void 0 ? void 0 : _a.historyProvider;
        return (_b = (await (historyProvider === null || historyProvider === void 0 ? void 0 : historyProvider.provideHistoryItemChanges(historyItemId, token)))) !== null && _b !== void 0 ? _b : undefined;
    }
}
exports.ExtHostSCM = ExtHostSCM;
ExtHostSCM._handlePool = 0;
//# sourceMappingURL=ext.host.scm.js.map