import { ServiceIdentifier } from '../../../../platform/instantiation/common/instantiation.js';
import { IRelativePattern } from '../../../../base/common/glob.js';
import { Event } from '../../../../base/common/event.js';
import { IDisposable } from '../../../../base/common/lifecycle.js';
import { URI } from '../../../../base/common/uri.js';
import { IResourceEditorInput, ITextResourceEditorInput } from '../../../../platform/editor/common/editor.js';
import { IUntypedEditorInput, EditorInputWithOptionsAndGroup, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IResourceMultiDiffEditorInput, IResourceMergeEditorInput, EditorInputWithOptions } from '../../../common/editor.js';
import { IEditorGroup } from './editorGroupsService.js';
import { PreferredGroup } from './editorService.js';
import { AtLeastOne } from '../../../../base/common/types.js';

type EditorAssociation = {
    readonly viewType: string;
    readonly filenamePattern?: string;
};
type EditorAssociations = readonly EditorAssociation[];
declare enum RegisteredEditorPriority {
    builtin = "builtin",
    option = "option",
    exclusive = "exclusive",
    default = "default"
}
/**
 * If we didn't resolve an editor dictates what to do with the opening state
 * ABORT = Do not continue with opening the editor
 * NONE = Continue as if the resolution has been disabled as the service could not resolve one
 */
declare const enum ResolvedStatus {
    ABORT = 1,
    NONE = 2
}
type ResolvedEditor = EditorInputWithOptionsAndGroup | ResolvedStatus;
type RegisteredEditorOptions = {
    /**
     * If your editor cannot be opened in multiple groups for the same resource
     */
    singlePerResource?: boolean | (() => boolean);
    /**
     * Whether or not you can support opening the given resource.
     * If omitted we assume you can open everything
     */
    canSupportResource?: (resource: URI) => boolean;
};
type RegisteredEditorInfo = {
    id: string;
    label: string;
    detail?: string;
    priority: RegisteredEditorPriority;
};
type EditorInputFactoryResult = EditorInputWithOptions | Promise<EditorInputWithOptions>;
type EditorInputFactoryFunction = (editorInput: IResourceEditorInput | ITextResourceEditorInput, group: IEditorGroup) => EditorInputFactoryResult;
type UntitledEditorInputFactoryFunction = (untitledEditorInput: IUntitledTextResourceEditorInput, group: IEditorGroup) => EditorInputFactoryResult;
type DiffEditorInputFactoryFunction = (diffEditorInput: IResourceDiffEditorInput, group: IEditorGroup) => EditorInputFactoryResult;
type MultiDiffEditorInputFactoryFunction = (multiDiffEditorInput: IResourceMultiDiffEditorInput, group: IEditorGroup) => EditorInputFactoryResult;
type MergeEditorInputFactoryFunction = (mergeEditorInput: IResourceMergeEditorInput, group: IEditorGroup) => EditorInputFactoryResult;
type EditorInputFactories = {
    createEditorInput?: EditorInputFactoryFunction;
    createUntitledEditorInput?: UntitledEditorInputFactoryFunction;
    createDiffEditorInput?: DiffEditorInputFactoryFunction;
    createMultiDiffEditorInput?: MultiDiffEditorInputFactoryFunction;
    createMergeEditorInput?: MergeEditorInputFactoryFunction;
};
type EditorInputFactoryObject = AtLeastOne<EditorInputFactories>;

declare const IEditorResolverService: ServiceIdentifier<IEditorResolverService>;
interface IEditorResolverService {
    readonly _serviceBrand: undefined;
    /**
     * Given a resource finds the editor associations that match it from the user's settings
     * @param resource The resource to match
     * @return The matching associations
     */
    getAssociationsForResource(resource: URI): EditorAssociations;
    /**
     * Updates the user's association to include a specific editor ID as a default for the given glob pattern
     * @param globPattern The glob pattern (must be a string as settings don't support relative glob)
     * @param editorID The ID of the editor to make a user default
     */
    updateUserAssociations(globPattern: string, editorID: string): void;
    /**
     * Emitted when an editor is registered or unregistered.
     */
    readonly onDidChangeEditorRegistrations: Event<void>;
    /**
     * Given a callback, run the callback pausing the registration emitter
     */
    bufferChangeEvents(callback: Function): void;
    /**
     * Registers a specific editor. Editors with the same glob pattern and ID will be grouped together by the resolver.
     * This allows for registration of the factories in different locations
     * @param globPattern The glob pattern for this registration
     * @param editorInfo Information about the registration
     * @param options Specific options which apply to this registration
     * @param editorFactoryObject The editor input factory functions
     */
    registerEditor(globPattern: string | IRelativePattern, editorInfo: RegisteredEditorInfo, options: RegisteredEditorOptions, editorFactoryObject: EditorInputFactoryObject): IDisposable;
    /**
     * Given an editor resolves it to the suitable ResolvedEitor based on user extensions, settings, and built-in editors
     * @param editor The editor to resolve
     * @param preferredGroup The group you want to open the editor in
     * @returns An EditorInputWithOptionsAndGroup if there is an available editor or a status of how to proceed
     */
    resolveEditor(editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ResolvedEditor>;
    /**
     * Given a resource returns all the editor ids that match that resource. If there is exclusive editor we return an empty array
     * @param resource The resource
     * @returns A list of editor ids
     */
    getEditors(resource: URI): RegisteredEditorInfo[];
    /**
     * A set of all the editors that are registered to the editor resolver.
     */
    getEditors(): RegisteredEditorInfo[];
    /**
     * Get a complete list of editor associations.
     */
    getAllUserAssociations(): EditorAssociations;
}

export { type DiffEditorInputFactoryFunction, type EditorAssociation, type EditorAssociations, type EditorInputFactoryFunction, type EditorInputFactoryObject, IEditorResolverService, type MergeEditorInputFactoryFunction, type MultiDiffEditorInputFactoryFunction, type RegisteredEditorInfo, type RegisteredEditorOptions, RegisteredEditorPriority, type ResolvedEditor, ResolvedStatus, type UntitledEditorInputFactoryFunction };
