
import { diffEditorDefaultOptions } from './diffEditor.js';
import { editorOptionsRegistry } from './editorOptions.js';
import { EDITOR_MODEL_DEFAULTS } from '../core/textModelDefaults.js';
import { localize } from '../../../nls.js';
import { ConfigurationScope, Extensions } from '../../../platform/configuration/common/configurationRegistry.js';
import { Registry } from '../../../platform/registry/common/platform.js';

const editorConfigurationBaseNode = ( Object.freeze({
    id: 'editor',
    order: 5,
    type: 'object',
    title: ( localize(210, "Editor")),
    scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
}));
const editorConfiguration = {
    ...editorConfigurationBaseNode,
    properties: {
        'editor.tabSize': {
            type: 'number',
            default: EDITOR_MODEL_DEFAULTS.tabSize,
            minimum: 1,
            maximum: 16,
            markdownDescription: ( localize(
                211,
                "The number of spaces a tab is equal to. This setting is overridden based on the file contents when {0} is on.",
                '`#editor.detectIndentation#`'
            ))
        },
        'editor.indentSize': {
            'anyOf': [
                {
                    type: 'string',
                    enum: ['tabSize']
                },
                {
                    type: 'number',
                    minimum: 1
                }
            ],
            default: 'tabSize',
            markdownDescription: ( localize(
                212,
                "The number of spaces used for indentation or `\"tabSize\"` to use the value from `#editor.tabSize#`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on."
            ))
        },
        'editor.insertSpaces': {
            type: 'boolean',
            default: EDITOR_MODEL_DEFAULTS.insertSpaces,
            markdownDescription: ( localize(
                213,
                "Insert spaces when pressing `Tab`. This setting is overridden based on the file contents when {0} is on.",
                '`#editor.detectIndentation#`'
            ))
        },
        'editor.detectIndentation': {
            type: 'boolean',
            default: EDITOR_MODEL_DEFAULTS.detectIndentation,
            markdownDescription: ( localize(
                214,
                "Controls whether {0} and {1} will be automatically detected when a file is opened based on the file contents.",
                '`#editor.tabSize#`',
                '`#editor.insertSpaces#`'
            ))
        },
        'editor.trimAutoWhitespace': {
            type: 'boolean',
            default: EDITOR_MODEL_DEFAULTS.trimAutoWhitespace,
            description: ( localize(215, "Remove trailing auto inserted whitespace."))
        },
        'editor.largeFileOptimizations': {
            type: 'boolean',
            default: EDITOR_MODEL_DEFAULTS.largeFileOptimizations,
            description: ( localize(
                216,
                "Special handling for large files to disable certain memory intensive features."
            ))
        },
        'editor.wordBasedSuggestions': {
            enum: ['off', 'currentDocument', 'matchingDocuments', 'allDocuments'],
            default: 'matchingDocuments',
            enumDescriptions: [
                ( localize(217, 'Turn off Word Based Suggestions.')),
                ( localize(218, 'Only suggest words from the active document.')),
                ( localize(219, 'Suggest words from all open documents of the same language.')),
                ( localize(220, 'Suggest words from all open documents.'))
            ],
            description: ( localize(
                221,
                "Controls whether completions should be computed based on words in the document and from which documents they are computed."
            ))
        },
        'editor.semanticHighlighting.enabled': {
            enum: [true, false, 'configuredByTheme'],
            enumDescriptions: [
                ( localize(222, 'Semantic highlighting enabled for all color themes.')),
                ( localize(223, 'Semantic highlighting disabled for all color themes.')),
                ( localize(
                224,
                'Semantic highlighting is configured by the current color theme\'s `semanticHighlighting` setting.'
            ))
            ],
            default: 'configuredByTheme',
            description: ( localize(
                225,
                "Controls whether the semanticHighlighting is shown for the languages that support it."
            ))
        },
        'editor.stablePeek': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                226,
                "Keep peek editors open even when double-clicking their content or when hitting `Escape`."
            ))
        },
        'editor.maxTokenizationLineLength': {
            type: 'integer',
            default: 20_000,
            description: ( localize(
                227,
                "Lines above this length will not be tokenized for performance reasons"
            ))
        },
        'editor.experimental.asyncTokenization': {
            type: 'boolean',
            default: true,
            description: ( localize(
                228,
                "Controls whether the tokenization should happen asynchronously on a web worker."
            )),
            tags: ['experimental'],
        },
        'editor.experimental.asyncTokenizationLogging': {
            type: 'boolean',
            default: false,
            description: ( localize(
                229,
                "Controls whether async tokenization should be logged. For debugging only."
            )),
        },
        'editor.experimental.asyncTokenizationVerification': {
            type: 'boolean',
            default: false,
            description: ( localize(
                230,
                "Controls whether async tokenization should be verified against legacy background tokenization. Might slow down tokenization. For debugging only."
            )),
            tags: ['experimental'],
        },
        'editor.experimental.treeSitterTelemetry': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                231,
                "Controls whether tree sitter parsing should be turned on and telemetry collected. Setting `editor.experimental.preferTreeSitter` for specific languages will take precedence."
            )),
            tags: ['experimental', 'onExP']
        },
        'editor.experimental.preferTreeSitter.css': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                232,
                "Controls whether tree sitter parsing should be turned on for css. This will take precedence over `editor.experimental.treeSitterTelemetry` for css."
            )),
            tags: ['experimental', 'onExP']
        },
        'editor.experimental.preferTreeSitter.typescript': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                233,
                "Controls whether tree sitter parsing should be turned on for typescript. This will take precedence over `editor.experimental.treeSitterTelemetry` for typescript."
            )),
            tags: ['experimental', 'onExP']
        },
        'editor.experimental.preferTreeSitter.ini': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                234,
                "Controls whether tree sitter parsing should be turned on for ini. This will take precedence over `editor.experimental.treeSitterTelemetry` for ini."
            )),
            tags: ['experimental', 'onExP']
        },
        'editor.experimental.preferTreeSitter.regex': {
            type: 'boolean',
            default: false,
            markdownDescription: ( localize(
                235,
                "Controls whether tree sitter parsing should be turned on for regex. This will take precedence over `editor.experimental.treeSitterTelemetry` for regex."
            )),
            tags: ['experimental', 'onExP']
        },
        'editor.language.brackets': {
            type: ['array', 'null'],
            default: null,
            description: ( localize(
                236,
                'Defines the bracket symbols that increase or decrease the indentation.'
            )),
            items: {
                type: 'array',
                items: [
                    {
                        type: 'string',
                        description: ( localize(237, 'The opening bracket character or string sequence.'))
                    },
                    {
                        type: 'string',
                        description: ( localize(238, 'The closing bracket character or string sequence.'))
                    }
                ]
            }
        },
        'editor.language.colorizedBracketPairs': {
            type: ['array', 'null'],
            default: null,
            description: ( localize(
                239,
                'Defines the bracket pairs that are colorized by their nesting level if bracket pair colorization is enabled.'
            )),
            items: {
                type: 'array',
                items: [
                    {
                        type: 'string',
                        description: ( localize(237, 'The opening bracket character or string sequence.'))
                    },
                    {
                        type: 'string',
                        description: ( localize(238, 'The closing bracket character or string sequence.'))
                    }
                ]
            }
        },
        'diffEditor.maxComputationTime': {
            type: 'number',
            default: diffEditorDefaultOptions.maxComputationTime,
            description: ( localize(
                240,
                "Timeout in milliseconds after which diff computation is cancelled. Use 0 for no timeout."
            ))
        },
        'diffEditor.maxFileSize': {
            type: 'number',
            default: diffEditorDefaultOptions.maxFileSize,
            description: ( localize(
                241,
                "Maximum file size in MB for which to compute diffs. Use 0 for no limit."
            ))
        },
        'diffEditor.renderSideBySide': {
            type: 'boolean',
            default: diffEditorDefaultOptions.renderSideBySide,
            description: ( localize(
                242,
                "Controls whether the diff editor shows the diff side by side or inline."
            ))
        },
        'diffEditor.renderSideBySideInlineBreakpoint': {
            type: 'number',
            default: diffEditorDefaultOptions.renderSideBySideInlineBreakpoint,
            description: ( localize(
                243,
                "If the diff editor width is smaller than this value, the inline view is used."
            ))
        },
        'diffEditor.useInlineViewWhenSpaceIsLimited': {
            type: 'boolean',
            default: diffEditorDefaultOptions.useInlineViewWhenSpaceIsLimited,
            description: ( localize(
                244,
                "If enabled and the editor width is too small, the inline view is used."
            ))
        },
        'diffEditor.renderMarginRevertIcon': {
            type: 'boolean',
            default: diffEditorDefaultOptions.renderMarginRevertIcon,
            description: ( localize(
                245,
                "When enabled, the diff editor shows arrows in its glyph margin to revert changes."
            ))
        },
        'diffEditor.renderGutterMenu': {
            type: 'boolean',
            default: diffEditorDefaultOptions.renderGutterMenu,
            description: ( localize(
                246,
                "When enabled, the diff editor shows a special gutter for revert and stage actions."
            ))
        },
        'diffEditor.ignoreTrimWhitespace': {
            type: 'boolean',
            default: diffEditorDefaultOptions.ignoreTrimWhitespace,
            description: ( localize(
                247,
                "When enabled, the diff editor ignores changes in leading or trailing whitespace."
            ))
        },
        'diffEditor.renderIndicators': {
            type: 'boolean',
            default: diffEditorDefaultOptions.renderIndicators,
            description: ( localize(
                248,
                "Controls whether the diff editor shows +/- indicators for added/removed changes."
            ))
        },
        'diffEditor.codeLens': {
            type: 'boolean',
            default: diffEditorDefaultOptions.diffCodeLens,
            description: ( localize(249, "Controls whether the editor shows CodeLens."))
        },
        'diffEditor.wordWrap': {
            type: 'string',
            enum: ['off', 'on', 'inherit'],
            default: diffEditorDefaultOptions.diffWordWrap,
            markdownEnumDescriptions: [
                ( localize(250, "Lines will never wrap.")),
                ( localize(251, "Lines will wrap at the viewport width.")),
                ( localize(
                252,
                "Lines will wrap according to the {0} setting.",
                '`#editor.wordWrap#`'
            )),
            ]
        },
        'diffEditor.diffAlgorithm': {
            type: 'string',
            enum: ['legacy', 'advanced'],
            default: diffEditorDefaultOptions.diffAlgorithm,
            markdownEnumDescriptions: [
                ( localize(253, "Uses the legacy diffing algorithm.")),
                ( localize(254, "Uses the advanced diffing algorithm.")),
            ]
        },
        'diffEditor.hideUnchangedRegions.enabled': {
            type: 'boolean',
            default: diffEditorDefaultOptions.hideUnchangedRegions.enabled,
            markdownDescription: ( localize(255, "Controls whether the diff editor shows unchanged regions.")),
        },
        'diffEditor.hideUnchangedRegions.revealLineCount': {
            type: 'integer',
            default: diffEditorDefaultOptions.hideUnchangedRegions.revealLineCount,
            markdownDescription: ( localize(256, "Controls how many lines are used for unchanged regions.")),
            minimum: 1,
        },
        'diffEditor.hideUnchangedRegions.minimumLineCount': {
            type: 'integer',
            default: diffEditorDefaultOptions.hideUnchangedRegions.minimumLineCount,
            markdownDescription: ( localize(
                257,
                "Controls how many lines are used as a minimum for unchanged regions."
            )),
            minimum: 1,
        },
        'diffEditor.hideUnchangedRegions.contextLineCount': {
            type: 'integer',
            default: diffEditorDefaultOptions.hideUnchangedRegions.contextLineCount,
            markdownDescription: ( localize(
                258,
                "Controls how many lines are used as context when comparing unchanged regions."
            )),
            minimum: 1,
        },
        'diffEditor.experimental.showMoves': {
            type: 'boolean',
            default: diffEditorDefaultOptions.experimental.showMoves,
            markdownDescription: ( localize(259, "Controls whether the diff editor should show detected code moves."))
        },
        'diffEditor.experimental.showEmptyDecorations': {
            type: 'boolean',
            default: diffEditorDefaultOptions.experimental.showEmptyDecorations,
            description: ( localize(
                260,
                "Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted."
            )),
        },
        'diffEditor.experimental.useTrueInlineView': {
            type: 'boolean',
            default: diffEditorDefaultOptions.experimental.useTrueInlineView,
            description: ( localize(
                261,
                "If enabled and the editor uses the inline view, word changes are rendered inline."
            )),
        },
    }
};
function isConfigurationPropertySchema(x) {
    return (typeof x.type !== 'undefined' || typeof x.anyOf !== 'undefined');
}
for (const editorOption of editorOptionsRegistry) {
    const schema = editorOption.schema;
    if (typeof schema !== 'undefined') {
        if (isConfigurationPropertySchema(schema)) {
            editorConfiguration.properties[`editor.${editorOption.name}`] = schema;
        }
        else {
            for (const key in schema) {
                if (Object.hasOwnProperty.call(schema, key)) {
                    editorConfiguration.properties[key] = schema[key];
                }
            }
        }
    }
}
let cachedEditorConfigurationKeys = null;
function getEditorConfigurationKeys() {
    if (cachedEditorConfigurationKeys === null) {
        cachedEditorConfigurationKeys = Object.create(null);
        ( Object.keys(editorConfiguration.properties)).forEach((prop) => {
            cachedEditorConfigurationKeys[prop] = true;
        });
    }
    return cachedEditorConfigurationKeys;
}
function isEditorConfigurationKey(key) {
    const editorConfigurationKeys = getEditorConfigurationKeys();
    return (editorConfigurationKeys[`editor.${key}`] || false);
}
function isDiffEditorConfigurationKey(key) {
    const editorConfigurationKeys = getEditorConfigurationKeys();
    return (editorConfigurationKeys[`diffEditor.${key}`] || false);
}
const configurationRegistry = ( Registry.as(Extensions.Configuration));
configurationRegistry.registerConfiguration(editorConfiguration);
async function registerEditorFontConfigurations(getFontSnippets) {
    const editorKeysWithFont = ['editor.fontFamily'];
    const fontSnippets = await getFontSnippets();
    for (const key of editorKeysWithFont) {
        if (editorConfiguration.properties && editorConfiguration.properties[key]) {
            editorConfiguration.properties[key].defaultSnippets = fontSnippets;
        }
    }
}

export { editorConfigurationBaseNode, isDiffEditorConfigurationKey, isEditorConfigurationKey, registerEditorFontConfigurations };
