
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { localize } from '../../../../nls.js';
import { Event } from '../../../../base/common/event.js';
import { onUnexpectedError } from '../../../../base/common/errors.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { InstallOperation } from '../../../../platform/extensionManagement/common/extensionManagement.js';
import { IExtensionManagementService } from '../../../../platform/extensionManagement/common/extensionManagement.service.js';
import { EnablementState } from '../../../services/extensionManagement/common/extensionManagement.js';
import { IWorkbenchExtensionEnablementService } from '../../../services/extensionManagement/common/extensionManagement.service.js';
import { IExtensionRecommendationsService } from '../../../services/extensionRecommendations/common/extensionRecommendations.service.js';
import { ILifecycleService } from '../../../services/lifecycle/common/lifecycle.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { areSameExtensions } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js';
import '../../../../platform/notification/common/notification.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import Severity$1 from '../../../../base/common/severity.js';

let KeymapExtensions = class KeymapExtensions extends Disposable {
    constructor(
        instantiationService,
        extensionEnablementService,
        tipsService,
        lifecycleService,
        notificationService
    ) {
        super();
        this.instantiationService = instantiationService;
        this.extensionEnablementService = extensionEnablementService;
        this.tipsService = tipsService;
        this.notificationService = notificationService;
        this._register(lifecycleService.onDidShutdown(() => this.dispose()));
        this._register(instantiationService.invokeFunction(onExtensionChanged)((identifiers => {
            Promise.all(( identifiers.map(identifier => this.checkForOtherKeymaps(identifier)))).then(undefined, onUnexpectedError);
        })));
    }
    checkForOtherKeymaps(extensionIdentifier) {
        return this.instantiationService.invokeFunction(getInstalledExtensions).then(extensions => {
            const keymaps = extensions.filter(extension => isKeymapExtension(this.tipsService, extension));
            const extension = keymaps.find(extension => areSameExtensions(extension.identifier, extensionIdentifier));
            if (extension && extension.globallyEnabled) {
                const otherKeymaps = keymaps.filter(
                    extension => !areSameExtensions(extension.identifier, extensionIdentifier) && extension.globallyEnabled
                );
                if (otherKeymaps.length) {
                    return this.promptForDisablingOtherKeymaps(extension, otherKeymaps);
                }
            }
            return undefined;
        });
    }
    promptForDisablingOtherKeymaps(newKeymap, oldKeymaps) {
        const onPrompt = confirmed => {
            if (confirmed) {
                this.extensionEnablementService.setEnablement(( oldKeymaps.map(keymap => keymap.local)), EnablementState.DisabledGlobally);
            }
        };
        this.notificationService.prompt(Severity$1.Info, ( localize(
            10243,
            "Disable other keymaps ({0}) to avoid conflicts between keybindings?",
            ( oldKeymaps.map(k => `'${k.local.manifest.displayName}'`)).join(", ")
        )), [{
            label: ( localize(10244, "Yes")),
            run: () => onPrompt(true)
        }, {
            label: ( localize(10245, "No")),
            run: () => onPrompt(false)
        }]);
    }
};
KeymapExtensions = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IWorkbenchExtensionEnablementService)), ( __param(2, IExtensionRecommendationsService)), ( __param(3, ILifecycleService)), ( __param(4, INotificationService))], KeymapExtensions));
function onExtensionChanged(accessor) {
    const extensionService = accessor.get(IExtensionManagementService);
    const extensionEnablementService = accessor.get(IWorkbenchExtensionEnablementService);
    const onDidInstallExtensions = Event.chain(extensionService.onDidInstallExtensions, $ => ( $.filter(e => ( e.some((
        {
            operation
        }
    ) => operation === InstallOperation.Install))).map(e => ( e.map((
        {
            identifier
        }
    ) => identifier)))));
    return Event.debounce(Event.any(Event.any(onDidInstallExtensions, ( Event.map(extensionService.onDidUninstallExtension, e => [e.identifier]))), ( Event.map(
        extensionEnablementService.onEnablementChanged,
        extensions => ( extensions.map(e => e.identifier))
    ))), (result, identifiers) => {
        result = result || [];
        for (const identifier of identifiers) {
            if (( result.some(l => !areSameExtensions(l, identifier)))) {
                result.push(identifier);
            }
        }
        return result;
    });
}
async function getInstalledExtensions(accessor) {
    const extensionService = accessor.get(IExtensionManagementService);
    const extensionEnablementService = accessor.get(IWorkbenchExtensionEnablementService);
    const extensions = await extensionService.getInstalled();
    return ( extensions.map(extension => {
        return {
            identifier: extension.identifier,
            local: extension,
            globallyEnabled: extensionEnablementService.isEnabled(extension)
        };
    }));
}
function isKeymapExtension(tipsService, extension) {
    const cats = extension.local.manifest.categories;
    return cats && cats.indexOf("Keymaps") !== -1 || ( tipsService.getKeymapRecommendations().some(extensionId => areSameExtensions({
        id: extensionId
    }, extension.local.identifier)));
}

export { KeymapExtensions, getInstalledExtensions };
