
import { localize } from '../../nls.js';
import { assertReturnsDefined } from '../../base/common/types.js';
import { URI } from '../../base/common/uri.js';
import { Disposable, toDisposable } from '../../base/common/lifecycle.js';
import { IInstantiationService } from '../../platform/instantiation/common/instantiation.js';
import { Registry } from '../../platform/registry/common/platform.js';
import { FileType } from '../../platform/files/common/files.js';
import { Schemas } from '../../base/common/network.js';
import { isErrorWithActions, createErrorWithActions } from '../../base/common/errorMessage.js';
import { toAction } from '../../base/common/actions.js';
import Severity$1 from '../../base/common/severity.js';

const EditorExtensions = {
    EditorPane: "workbench.contributions.editors",
    EditorFactory: "workbench.contributions.editor.inputFactories"
};
const DEFAULT_EDITOR_ASSOCIATION = {
    id: "default",
    displayName: ( localize(4157, "Text Editor")),
    providerDisplayName: ( localize(4158, "Built-in"))
};
const SIDE_BY_SIDE_EDITOR_ID = "workbench.editor.sidebysideEditor";
const TEXT_DIFF_EDITOR_ID = "workbench.editors.textDiffEditor";
const BINARY_DIFF_EDITOR_ID = "workbench.editors.binaryResourceDiffEditor";
var EditorPaneSelectionChangeReason;
(function(EditorPaneSelectionChangeReason) {
    EditorPaneSelectionChangeReason[EditorPaneSelectionChangeReason["PROGRAMMATIC"] = 1] = "PROGRAMMATIC";
    EditorPaneSelectionChangeReason[EditorPaneSelectionChangeReason["USER"] = 2] = "USER";
    EditorPaneSelectionChangeReason[EditorPaneSelectionChangeReason["EDIT"] = 3] = "EDIT";
    EditorPaneSelectionChangeReason[EditorPaneSelectionChangeReason["NAVIGATION"] = 4] = "NAVIGATION";
    EditorPaneSelectionChangeReason[EditorPaneSelectionChangeReason["JUMP"] = 5] = "JUMP";
})(EditorPaneSelectionChangeReason || (EditorPaneSelectionChangeReason = {}));
var EditorPaneSelectionCompareResult;
(function(EditorPaneSelectionCompareResult) {
    EditorPaneSelectionCompareResult[EditorPaneSelectionCompareResult["IDENTICAL"] = 1] = "IDENTICAL";
    EditorPaneSelectionCompareResult[EditorPaneSelectionCompareResult["SIMILAR"] = 2] = "SIMILAR";
    EditorPaneSelectionCompareResult[EditorPaneSelectionCompareResult["DIFFERENT"] = 3] = "DIFFERENT";
})(
    EditorPaneSelectionCompareResult || (EditorPaneSelectionCompareResult = {})
);
function isEditorPaneWithSelection(editorPane) {
    const candidate = editorPane;
    return !!candidate && typeof candidate.getSelection === "function" && !!candidate.onDidChangeSelection;
}
function isEditorPaneWithScrolling(editorPane) {
    const candidate = editorPane;
    return !!candidate && typeof candidate.getScrollPosition === "function" && typeof candidate.setScrollPosition === "function" && !!candidate.onDidChangeScroll;
}
function findViewStateForEditor(input, group, editorService) {
    for (const editorPane of editorService.visibleEditorPanes) {
        if (editorPane.group.id === group && input.matches(editorPane.input)) {
            return editorPane.getViewState();
        }
    }
    return undefined;
}
function isResourceEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    return URI.isUri(candidate?.resource);
}
function isResourceDiffEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    return candidate?.original !== undefined && candidate.modified !== undefined;
}
function isResourceMultiDiffEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    if (!candidate) {
        return false;
    }
    if (candidate.resources && !Array.isArray(candidate.resources)) {
        return false;
    }
    return !!candidate.resources || !!candidate.multiDiffSource;
}
function isResourceSideBySideEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    if (isResourceDiffEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    return candidate?.primary !== undefined && candidate.secondary !== undefined;
}
function isUntitledResourceEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    if (!candidate) {
        return false;
    }
    return candidate.resource === undefined || candidate.resource.scheme === Schemas.untitled || candidate.forceUntitled === true;
}
function isResourceMergeEditorInput(editor) {
    if (isEditorInput(editor)) {
        return false;
    }
    const candidate = editor;
    return URI.isUri(candidate?.base?.resource) && URI.isUri(candidate?.input1?.resource) && URI.isUri(candidate?.input2?.resource) && URI.isUri(candidate?.result?.resource);
}
var Verbosity;
(function(Verbosity) {
    Verbosity[Verbosity["SHORT"] = 0] = "SHORT";
    Verbosity[Verbosity["MEDIUM"] = 1] = "MEDIUM";
    Verbosity[Verbosity["LONG"] = 2] = "LONG";
})(Verbosity || (Verbosity = {}));
var SaveReason;
(function(SaveReason) {
    SaveReason[SaveReason["EXPLICIT"] = 1] = "EXPLICIT";
    SaveReason[SaveReason["AUTO"] = 2] = "AUTO";
    SaveReason[SaveReason["FOCUS_CHANGE"] = 3] = "FOCUS_CHANGE";
    SaveReason[SaveReason["WINDOW_CHANGE"] = 4] = "WINDOW_CHANGE";
})(SaveReason || (SaveReason = {}));
class SaveSourceFactory {
    constructor() {
        this.mapIdToSaveSource = ( new Map());
    }
    registerSource(id, label) {
        let sourceDescriptor = this.mapIdToSaveSource.get(id);
        if (!sourceDescriptor) {
            sourceDescriptor = {
                source: id,
                label
            };
            this.mapIdToSaveSource.set(id, sourceDescriptor);
        }
        return sourceDescriptor.source;
    }
    getSourceLabel(source) {
        return this.mapIdToSaveSource.get(source)?.label ?? source;
    }
}
const SaveSourceRegistry = ( new SaveSourceFactory());
var EditorInputCapabilities;
(function(EditorInputCapabilities) {
    EditorInputCapabilities[EditorInputCapabilities["None"] = 0] = "None";
    EditorInputCapabilities[EditorInputCapabilities["Readonly"] = 2] = "Readonly";
    EditorInputCapabilities[EditorInputCapabilities["Untitled"] = 4] = "Untitled";
    EditorInputCapabilities[EditorInputCapabilities["Singleton"] = 8] = "Singleton";
    EditorInputCapabilities[EditorInputCapabilities["RequiresTrust"] = 16] = "RequiresTrust";
    EditorInputCapabilities[EditorInputCapabilities["CanSplitInGroup"] = 32] = "CanSplitInGroup";
    EditorInputCapabilities[EditorInputCapabilities["ForceDescription"] = 64] = "ForceDescription";
    EditorInputCapabilities[EditorInputCapabilities["CanDropIntoEditor"] = 128] = "CanDropIntoEditor";
    EditorInputCapabilities[EditorInputCapabilities["MultipleEditors"] = 256] = "MultipleEditors";
    EditorInputCapabilities[EditorInputCapabilities["Scratchpad"] = 512] = "Scratchpad";
    EditorInputCapabilities[EditorInputCapabilities["ForceReveal"] = 1024] = "ForceReveal";
    EditorInputCapabilities[EditorInputCapabilities["RequiresModal"] = 2048] = "RequiresModal";
})(EditorInputCapabilities || (EditorInputCapabilities = {}));
class AbstractEditorInput extends Disposable {}
function isEditorInput(editor) {
    return editor instanceof AbstractEditorInput;
}
function isEditorInputWithPreferredResource(editor) {
    const candidate = editor;
    return URI.isUri(candidate?.preferredResource);
}
function isSideBySideEditorInput(editor) {
    const candidate = editor;
    return isEditorInput(candidate?.primary) && isEditorInput(candidate?.secondary);
}
function isDiffEditorInput(editor) {
    const candidate = editor;
    return isEditorInput(candidate?.modified) && isEditorInput(candidate?.original);
}
function createTooLargeFileError(group, input, options, message, preferencesService) {
    return createEditorOpenError(message, [toAction({
        id: "workbench.action.openLargeFile",
        label: ( localize(4159, "Open Anyway")),
        run: () => {
            const fileEditorOptions = {
                ...options,
                limits: {
                    size: Number.MAX_VALUE
                }
            };
            group.openEditor(input, fileEditorOptions);
        }
    }), toAction({
        id: "workbench.action.configureEditorLargeFileConfirmation",
        label: ( localize(4160, "Configure Limit")),
        run: () => {
            return preferencesService.openUserSettings({
                query: "workbench.editorLargeFileConfirmation"
            });
        }
    })], {
        forceMessage: true,
        forceSeverity: Severity$1.Warning
    });
}
function isEditorInputWithOptions(editor) {
    const candidate = editor;
    return isEditorInput(candidate?.editor);
}
function isEditorInputWithOptionsAndGroup(editor) {
    const candidate = editor;
    return isEditorInputWithOptions(editor) && candidate?.group !== undefined;
}
function isEditorIdentifier(identifier) {
    const candidate = identifier;
    return typeof candidate?.groupId === "number" && isEditorInput(candidate.editor);
}
function isEditorCommandsContext(context) {
    const candidate = context;
    return typeof candidate?.groupId === "number";
}
var EditorCloseContext;
(function(EditorCloseContext) {
    EditorCloseContext[EditorCloseContext["UNKNOWN"] = 0] = "UNKNOWN";
    EditorCloseContext[EditorCloseContext["REPLACE"] = 1] = "REPLACE";
    EditorCloseContext[EditorCloseContext["MOVE"] = 2] = "MOVE";
    EditorCloseContext[EditorCloseContext["UNPIN"] = 3] = "UNPIN";
})(EditorCloseContext || (EditorCloseContext = {}));
var GroupModelChangeKind;
(function(GroupModelChangeKind) {
    GroupModelChangeKind[GroupModelChangeKind["GROUP_ACTIVE"] = 0] = "GROUP_ACTIVE";
    GroupModelChangeKind[GroupModelChangeKind["GROUP_INDEX"] = 1] = "GROUP_INDEX";
    GroupModelChangeKind[GroupModelChangeKind["GROUP_LABEL"] = 2] = "GROUP_LABEL";
    GroupModelChangeKind[GroupModelChangeKind["GROUP_LOCKED"] = 3] = "GROUP_LOCKED";
    GroupModelChangeKind[GroupModelChangeKind["EDITORS_SELECTION"] = 4] = "EDITORS_SELECTION";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_OPEN"] = 5] = "EDITOR_OPEN";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_CLOSE"] = 6] = "EDITOR_CLOSE";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_MOVE"] = 7] = "EDITOR_MOVE";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_ACTIVE"] = 8] = "EDITOR_ACTIVE";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_LABEL"] = 9] = "EDITOR_LABEL";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_CAPABILITIES"] = 10] = "EDITOR_CAPABILITIES";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_PIN"] = 11] = "EDITOR_PIN";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_TRANSIENT"] = 12] = "EDITOR_TRANSIENT";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_STICKY"] = 13] = "EDITOR_STICKY";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_DIRTY"] = 14] = "EDITOR_DIRTY";
    GroupModelChangeKind[GroupModelChangeKind["EDITOR_WILL_DISPOSE"] = 15] = "EDITOR_WILL_DISPOSE";
})(GroupModelChangeKind || (GroupModelChangeKind = {}));
var SideBySideEditor;
(function(SideBySideEditor) {
    SideBySideEditor[SideBySideEditor["PRIMARY"] = 1] = "PRIMARY";
    SideBySideEditor[SideBySideEditor["SECONDARY"] = 2] = "SECONDARY";
    SideBySideEditor[SideBySideEditor["BOTH"] = 3] = "BOTH";
    SideBySideEditor[SideBySideEditor["ANY"] = 4] = "ANY";
})(SideBySideEditor || (SideBySideEditor = {}));
class EditorResourceAccessorImpl {
    getOriginalUri(editor, options) {
        if (!editor) {
            return undefined;
        }
        if (isResourceMergeEditorInput(editor)) {
            return EditorResourceAccessor.getOriginalUri(editor.result, options);
        }
        if (options?.supportSideBySide) {
            const {
                primary,
                secondary
            } = this.getSideEditors(editor);
            if (primary && secondary) {
                if (options?.supportSideBySide === SideBySideEditor.BOTH) {
                    return {
                        primary: this.getOriginalUri(primary, {
                            filterByScheme: options.filterByScheme
                        }),
                        secondary: this.getOriginalUri(secondary, {
                            filterByScheme: options.filterByScheme
                        })
                    };
                } else if (options?.supportSideBySide === SideBySideEditor.ANY) {
                    return this.getOriginalUri(primary, {
                        filterByScheme: options.filterByScheme
                    }) ?? this.getOriginalUri(secondary, {
                        filterByScheme: options.filterByScheme
                    });
                }
                editor = options.supportSideBySide === SideBySideEditor.PRIMARY ? primary : secondary;
            }
        }
        if (isResourceDiffEditorInput(editor) || isResourceMultiDiffEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) {
            return undefined;
        }
        const originalResource = isEditorInputWithPreferredResource(editor) ? editor.preferredResource : editor.resource;
        if (!originalResource || !options?.filterByScheme) {
            return originalResource;
        }
        return this.filterUri(originalResource, options.filterByScheme);
    }
    getSideEditors(editor) {
        if (isSideBySideEditorInput(editor) || isResourceSideBySideEditorInput(editor)) {
            return {
                primary: editor.primary,
                secondary: editor.secondary
            };
        }
        if (isDiffEditorInput(editor) || isResourceDiffEditorInput(editor)) {
            return {
                primary: editor.modified,
                secondary: editor.original
            };
        }
        return {
            primary: undefined,
            secondary: undefined
        };
    }
    getCanonicalUri(editor, options) {
        if (!editor) {
            return undefined;
        }
        if (isResourceMergeEditorInput(editor)) {
            return EditorResourceAccessor.getCanonicalUri(editor.result, options);
        }
        if (options?.supportSideBySide) {
            const {
                primary,
                secondary
            } = this.getSideEditors(editor);
            if (primary && secondary) {
                if (options?.supportSideBySide === SideBySideEditor.BOTH) {
                    return {
                        primary: this.getCanonicalUri(primary, {
                            filterByScheme: options.filterByScheme
                        }),
                        secondary: this.getCanonicalUri(secondary, {
                            filterByScheme: options.filterByScheme
                        })
                    };
                } else if (options?.supportSideBySide === SideBySideEditor.ANY) {
                    return this.getCanonicalUri(primary, {
                        filterByScheme: options.filterByScheme
                    }) ?? this.getCanonicalUri(secondary, {
                        filterByScheme: options.filterByScheme
                    });
                }
                editor = options.supportSideBySide === SideBySideEditor.PRIMARY ? primary : secondary;
            }
        }
        if (isResourceDiffEditorInput(editor) || isResourceMultiDiffEditorInput(editor) || isResourceSideBySideEditorInput(editor) || isResourceMergeEditorInput(editor)) {
            return undefined;
        }
        const canonicalResource = editor.resource;
        if (!canonicalResource || !options?.filterByScheme) {
            return canonicalResource;
        }
        return this.filterUri(canonicalResource, options.filterByScheme);
    }
    filterUri(resource, filter) {
        if (Array.isArray(filter)) {
            if (( filter.some(scheme => resource.scheme === scheme))) {
                return resource;
            }
        }
        else {
            if (filter === resource.scheme) {
                return resource;
            }
        }
        return undefined;
    }
}
var EditorCloseMethod;
(function(EditorCloseMethod) {
    EditorCloseMethod[EditorCloseMethod["UNKNOWN"] = 0] = "UNKNOWN";
    EditorCloseMethod[EditorCloseMethod["KEYBOARD"] = 1] = "KEYBOARD";
    EditorCloseMethod[EditorCloseMethod["MOUSE"] = 2] = "MOUSE";
})(EditorCloseMethod || (EditorCloseMethod = {}));
function preventEditorClose(group, editor, method, configuration) {
    if (!group.isSticky(editor)) {
        return false;
    }
    switch (configuration.preventPinnedEditorClose) {
    case "keyboardAndMouse":
        return method === EditorCloseMethod.MOUSE || method === EditorCloseMethod.KEYBOARD;
    case "mouse":
        return method === EditorCloseMethod.MOUSE;
    case "keyboard":
        return method === EditorCloseMethod.KEYBOARD;
    }
    return false;
}
const EditorResourceAccessor = ( new EditorResourceAccessorImpl());
var CloseDirection;
(function(CloseDirection) {
    CloseDirection[CloseDirection["LEFT"] = 0] = "LEFT";
    CloseDirection[CloseDirection["RIGHT"] = 1] = "RIGHT";
})(CloseDirection || (CloseDirection = {}));
class EditorFactoryRegistry {
    constructor() {
        this.editorSerializerConstructors = ( new Map());
        this.editorSerializerInstances = ( new Map());
    }
    start(accessor) {
        const instantiationService = this.instantiationService = accessor.get(IInstantiationService);
        for (const [key, ctor] of this.editorSerializerConstructors) {
            this.createEditorSerializer(key, ctor, instantiationService);
        }
        this.editorSerializerConstructors.clear();
    }
    createEditorSerializer(editorTypeId, ctor, instantiationService) {
        const instance = instantiationService.createInstance(ctor);
        this.editorSerializerInstances.set(editorTypeId, instance);
    }
    registerFileEditorFactory(factory) {
        if (this.fileEditorFactory) {
            throw ( new Error("Can only register one file editor factory."));
        }
        this.fileEditorFactory = factory;
    }
    getFileEditorFactory() {
        return assertReturnsDefined(this.fileEditorFactory);
    }
    registerEditorSerializer(editorTypeId, ctor) {
        if (( this.editorSerializerConstructors.has(editorTypeId)) || ( this.editorSerializerInstances.has(editorTypeId))) {
            throw ( new Error(
                `A editor serializer with type ID '${editorTypeId}' was already registered.`
            ));
        }
        if (!this.instantiationService) {
            this.editorSerializerConstructors.set(editorTypeId, ctor);
        } else {
            this.createEditorSerializer(editorTypeId, ctor, this.instantiationService);
        }
        return toDisposable(() => {
            this.editorSerializerConstructors.delete(editorTypeId);
            this.editorSerializerInstances.delete(editorTypeId);
        });
    }
    getEditorSerializer(arg1) {
        return this.editorSerializerInstances.get(typeof arg1 === "string" ? arg1 : arg1.typeId);
    }
}
Registry.add(EditorExtensions.EditorFactory, ( new EditorFactoryRegistry()));
async function pathsToEditors(paths, fileService, logService) {
    if (!paths?.length) {
        return [];
    }
    return await Promise.all(( paths.map(async path => {
        const resource = URI.revive(path.fileUri);
        if (!resource) {
            logService.info("Cannot resolve the path because it is not valid.", path);
            return undefined;
        }
        const canHandleResource = await fileService.canHandleResource(resource);
        if (!canHandleResource) {
            logService.info("Cannot resolve the path because it cannot be handled", path);
            return undefined;
        }
        let exists = path.exists;
        let type = path.type;
        if (typeof exists !== "boolean" || typeof type !== "number") {
            try {
                type = (await fileService.stat(resource)).isDirectory ? FileType.Directory : FileType.Unknown;
                exists = true;
            } catch (error) {
                logService.error(error);
                exists = false;
            }
        }
        if (!exists && path.openOnlyIfExists) {
            logService.info("Cannot resolve the path because it does not exist", path);
            return undefined;
        }
        if (type === FileType.Directory) {
            logService.info("Cannot resolve the path because it is a directory", path);
            return undefined;
        }
        const options = {
            ...path.options,
            pinned: true
        };
        if (!exists) {
            return {
                resource,
                options,
                forceUntitled: true
            };
        }
        return {
            resource,
            options
        };
    })));
}
var EditorsOrder;
(function(EditorsOrder) {
    EditorsOrder[EditorsOrder["MOST_RECENTLY_ACTIVE"] = 0] = "MOST_RECENTLY_ACTIVE";
    EditorsOrder[EditorsOrder["SEQUENTIAL"] = 1] = "SEQUENTIAL";
})(EditorsOrder || (EditorsOrder = {}));
function isTextEditorViewState(candidate) {
    const viewState = candidate;
    if (!viewState) {
        return false;
    }
    const diffEditorViewState = viewState;
    if (diffEditorViewState.modified) {
        return isTextEditorViewState(diffEditorViewState.modified);
    }
    const codeEditorViewState = viewState;
    return !!(codeEditorViewState.contributionsState && codeEditorViewState.viewState && Array.isArray(codeEditorViewState.cursorState));
}
function isEditorOpenError(obj) {
    return isErrorWithActions(obj);
}
function createEditorOpenError(messageOrError, actions, options) {
    const error = createErrorWithActions(messageOrError, actions);
    error.forceMessage = options?.forceMessage;
    error.forceSeverity = options?.forceSeverity;
    error.allowDialog = options?.allowDialog;
    return error;
}

export { AbstractEditorInput, BINARY_DIFF_EDITOR_ID, CloseDirection, DEFAULT_EDITOR_ASSOCIATION, EditorCloseContext, EditorCloseMethod, EditorExtensions, EditorInputCapabilities, EditorPaneSelectionChangeReason, EditorPaneSelectionCompareResult, EditorResourceAccessor, EditorsOrder, GroupModelChangeKind, SIDE_BY_SIDE_EDITOR_ID, SaveReason, SaveSourceRegistry, SideBySideEditor, TEXT_DIFF_EDITOR_ID, Verbosity, createEditorOpenError, createTooLargeFileError, findViewStateForEditor, isDiffEditorInput, isEditorCommandsContext, isEditorIdentifier, isEditorInput, isEditorInputWithOptions, isEditorInputWithOptionsAndGroup, isEditorOpenError, isEditorPaneWithScrolling, isEditorPaneWithSelection, isResourceDiffEditorInput, isResourceEditorInput, isResourceMergeEditorInput, isResourceMultiDiffEditorInput, isResourceSideBySideEditorInput, isSideBySideEditorInput, isTextEditorViewState, isUntitledResourceEditorInput, pathsToEditors, preventEditorClose };
