import { IStringDictionary } from '../../../../base/common/collections.js';
import { Event } from '../../../../base/common/event.js';
import { IJSONSchemaMap, IJSONSchema } from '../../../../base/common/jsonSchema.js';
import { URI } from '../../../../base/common/uri.js';
import { IRange } from '../../../../editor/common/core/range.js';
import '../../../../editor/editor.api.js';
import { ConfigurationScope, IExtensionInfo, EditPresentationTypes, ConfigurationDefaultValueSource } from '../../../../platform/configuration/common/configurationRegistry.js';
import { ConfigurationTarget } from '../../../../platform/configuration/common/configuration.js';
import { IEditorOptions } from '../../../../platform/editor/common/editor.js';

interface ISettingsGroup {
    id: string;
    range: IRange;
    title: string;
    titleRange: IRange;
    sections: ISettingsSection[];
    order?: number;
    extensionInfo?: IExtensionInfo;
}
interface ISettingsSection {
    titleRange?: IRange;
    title?: string;
    settings: ISetting[];
}
interface ISetting {
    range: IRange;
    key: string;
    keyRange: IRange;
    value: any;
    valueRange: IRange;
    description: string[];
    descriptionIsMarkdown?: boolean;
    descriptionRanges: IRange[];
    overrides?: ISetting[];
    overrideOf?: ISetting;
    deprecationMessage?: string;
    deprecationMessageIsMarkdown?: boolean;
    scope?: ConfigurationScope;
    type?: string | string[];
    order?: number;
    arrayItemType?: string;
    objectProperties?: IJSONSchemaMap;
    objectPatternProperties?: IJSONSchemaMap;
    objectAdditionalProperties?: boolean | IJSONSchema;
    enum?: string[];
    enumDescriptions?: string[];
    enumDescriptionsAreMarkdown?: boolean;
    uniqueItems?: boolean;
    tags?: string[];
    disallowSyncIgnore?: boolean;
    restricted?: boolean;
    extensionInfo?: IExtensionInfo;
    validator?: (value: any) => string | null;
    enumItemLabels?: string[];
    allKeysAreBoolean?: boolean;
    editPresentation?: EditPresentationTypes;
    nonLanguageSpecificDefaultValueSource?: ConfigurationDefaultValueSource;
    isLanguageTagSetting?: boolean;
    categoryLabel?: string;
    displayExtensionId?: string;
    stableExtensionId?: string;
    prereleaseExtensionId?: string;
    title?: string;
    extensionGroupTitle?: string;
    internalOrder?: number;
}
interface ISearchResult {
    filterMatches: ISettingMatch[];
    exactMatch?: boolean;
    metadata?: IFilterMetadata;
}
interface ISearchResultGroup {
    id: string;
    label: string;
    result: ISearchResult;
    order: number;
}
interface IFilterResult {
    query?: string;
    filteredGroups: ISettingsGroup[];
    allGroups: ISettingsGroup[];
    matches: IRange[];
    metadata?: IStringDictionary<IFilterMetadata>;
    exactMatch?: boolean;
}
/**
 * The ways a setting could match a query,
 * sorted in increasing order of relevance.
 */
declare enum SettingMatchType {
    None = 0,
    LanguageTagSettingMatch = 1,
    RemoteMatch = 2,
    DescriptionOrValueMatch = 4,
    KeyMatch = 8
}
interface ISettingMatch {
    setting: ISetting;
    matches: IRange[] | null;
    matchType: SettingMatchType;
    score: number;
}
interface IScoredResults {
    [key: string]: IRemoteSetting;
}
interface IRemoteSetting {
    score: number;
    key: string;
    id: string;
    defaultValue: string;
    description: string;
    packageId: string;
    extensionName?: string;
    extensionPublisher?: string;
}
interface IFilterMetadata {
    requestUrl: string;
    requestBody: string;
    timestamp: number;
    duration: number;
    scoredResults: IScoredResults;
    /** The number of requests made, since requests are split by number of filters */
    requestCount?: number;
    /** The name of the server that actually served the request */
    context: string;
}
interface IPreferencesEditorModel<T> {
    uri?: URI;
    getPreference(key: string): T | undefined;
    dispose(): void;
}
type IGroupFilter = (group: ISettingsGroup) => boolean | null;
type ISettingMatcher = (setting: ISetting, group: ISettingsGroup) => {
    matches: IRange[];
    matchType: SettingMatchType;
    score: number;
} | null;
interface ISettingsEditorModel extends IPreferencesEditorModel<ISetting> {
    readonly onDidChangeGroups: Event<void>;
    settingsGroups: ISettingsGroup[];
    filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher): ISettingMatch[];
    findValueMatches(filter: string, setting: ISetting): IRange[];
    updateResultGroup(id: string, resultGroup: ISearchResultGroup | undefined): IFilterResult | undefined;
}
interface ISettingsEditorOptions extends IEditorOptions {
    target?: ConfigurationTarget;
    folderUri?: URI;
    query?: string;
    /**
     * Only works when opening the json settings file. Use `query` for settings editor.
     */
    revealSetting?: {
        key: string;
        edit?: boolean;
    };
    focusSearch?: boolean;
}
interface IOpenSettingsOptions extends ISettingsEditorOptions {
    jsonEditor?: boolean;
    openToSide?: boolean;
}
interface IKeybindingsEditorOptions extends IEditorOptions {
    query?: string;
}

export { type IFilterMetadata, type IFilterResult, type IGroupFilter, type IKeybindingsEditorOptions, type IOpenSettingsOptions, type IPreferencesEditorModel, type IRemoteSetting, type IScoredResults, type ISearchResult, type ISearchResultGroup, type ISetting, type ISettingMatch, type ISettingMatcher, type ISettingsEditorModel, type ISettingsEditorOptions, type ISettingsGroup, type ISettingsSection, SettingMatchType };
