
import { HierarchicalKind } from '../../../../base/common/hierarchicalKind.js';
import { KeyMod as KeyMod$1, KeyCode } from '../../../../base/common/keyCodes.js';
import { escapeRegExpCharacters } from '../../../../base/common/strings.js';
import { EditorAction, EditorCommand } from '../../../browser/editorExtensions.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { quickFixCommandId, codeActionCommandId, refactorCommandId, sourceActionCommandId, organizeImportsCommandId, fixAllCommandId, autoFixCommandId } from './codeAction.js';
import { localize, localize2 } from '../../../../nls.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { CodeActionAutoApply, CodeActionTriggerSource, CodeActionCommandArgs, CodeActionKind } from '../common/types.js';
import { CodeActionController } from './codeActionController.js';
import { SUPPORTED_CODE_ACTIONS } from './codeActionModel.js';

function contextKeyForSupportedActions(kind) {
    return ( ContextKeyExpr.regex(( SUPPORTED_CODE_ACTIONS.keys())[0], ( new RegExp('(\\s|^)' + escapeRegExpCharacters(kind.value) + '\\b'))));
}
const argsSchema = {
    type: 'object',
    defaultSnippets: [{ body: { kind: '' } }],
    properties: {
        'kind': {
            type: 'string',
            description: ( localize(894, "Kind of the code action to run.")),
        },
        'apply': {
            type: 'string',
            description: ( localize(895, "Controls when the returned actions are applied.")),
            default: CodeActionAutoApply.IfSingle,
            enum: [CodeActionAutoApply.First, CodeActionAutoApply.IfSingle, CodeActionAutoApply.Never],
            enumDescriptions: [
                ( localize(896, "Always apply the first returned code action.")),
                ( localize(897, "Apply the first returned code action if it is the only one.")),
                ( localize(898, "Do not apply the returned code actions.")),
            ]
        },
        'preferred': {
            type: 'boolean',
            default: false,
            description: ( localize(899, "Controls if only preferred code actions should be returned.")),
        }
    }
};
function triggerCodeActionsForEditorSelection(editor, notAvailableMessage, filter, autoApply, triggerAction = CodeActionTriggerSource.Default) {
    if (editor.hasModel()) {
        const controller = CodeActionController.get(editor);
        controller?.manualTriggerAtCurrentPosition(notAvailableMessage, triggerAction, filter, autoApply);
    }
}
class QuickFixAction extends EditorAction {
    constructor() {
        super({
            id: quickFixCommandId,
            label: ( localize2(900, "Quick Fix...")),
            precondition: ( ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider)),
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: KeyMod$1.CtrlCmd | KeyCode.Period,
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
    run(_accessor, editor) {
        return triggerCodeActionsForEditorSelection(editor, ( localize(901, "No code actions available")), undefined, undefined, CodeActionTriggerSource.QuickFix);
    }
}
class CodeActionCommand extends EditorCommand {
    constructor() {
        super({
            id: codeActionCommandId,
            precondition: ( ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider)),
            metadata: {
                description: 'Trigger a code action',
                args: [{ name: 'args', schema: argsSchema, }]
            }
        });
    }
    runEditorCommand(_accessor, editor, userArgs) {
        const args = CodeActionCommandArgs.fromUser(userArgs, {
            kind: HierarchicalKind.Empty,
            apply: CodeActionAutoApply.IfSingle,
        });
        return triggerCodeActionsForEditorSelection(editor, typeof userArgs?.kind === 'string'
            ? args.preferred
                ? ( localize(902, "No preferred code actions for '{0}' available", userArgs.kind))
                : ( localize(903, "No code actions for '{0}' available", userArgs.kind))
            : args.preferred
                ? ( localize(904, "No preferred code actions available"))
                : ( localize(905, "No code actions available")), {
            include: args.kind,
            includeSourceActions: true,
            onlyIncludePreferredActions: args.preferred,
        }, args.apply);
    }
}
class RefactorAction extends EditorAction {
    constructor() {
        super({
            id: refactorCommandId,
            label: ( localize2(906, "Refactor...")),
            precondition: ( ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider)),
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: KeyMod$1.CtrlCmd | KeyMod$1.Shift | KeyCode.KeyR,
                mac: {
                    primary: KeyMod$1.WinCtrl | KeyMod$1.Shift | KeyCode.KeyR
                },
                weight: KeybindingWeight.EditorContrib
            },
            contextMenuOpts: {
                group: '1_modification',
                order: 2,
                when: ( ContextKeyExpr.and(
                    EditorContextKeys.writable,
                    contextKeyForSupportedActions(CodeActionKind.Refactor)
                )),
            },
            metadata: {
                description: 'Refactor...',
                args: [{ name: 'args', schema: argsSchema }]
            }
        });
    }
    run(_accessor, editor, userArgs) {
        const args = CodeActionCommandArgs.fromUser(userArgs, {
            kind: CodeActionKind.Refactor,
            apply: CodeActionAutoApply.Never
        });
        return triggerCodeActionsForEditorSelection(editor, typeof userArgs?.kind === 'string'
            ? args.preferred
                ? ( localize(907, "No preferred refactorings for '{0}' available", userArgs.kind))
                : ( localize(908, "No refactorings for '{0}' available", userArgs.kind))
            : args.preferred
                ? ( localize(909, "No preferred refactorings available"))
                : ( localize(910, "No refactorings available")), {
            include: CodeActionKind.Refactor.contains(args.kind) ? args.kind : HierarchicalKind.None,
            onlyIncludePreferredActions: args.preferred
        }, args.apply, CodeActionTriggerSource.Refactor);
    }
}
class SourceAction extends EditorAction {
    constructor() {
        super({
            id: sourceActionCommandId,
            label: ( localize2(911, "Source Action...")),
            precondition: ( ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasCodeActionsProvider)),
            contextMenuOpts: {
                group: '1_modification',
                order: 2.1,
                when: ( ContextKeyExpr.and(
                    EditorContextKeys.writable,
                    contextKeyForSupportedActions(CodeActionKind.Source)
                )),
            },
            metadata: {
                description: 'Source Action...',
                args: [{ name: 'args', schema: argsSchema }]
            }
        });
    }
    run(_accessor, editor, userArgs) {
        const args = CodeActionCommandArgs.fromUser(userArgs, {
            kind: CodeActionKind.Source,
            apply: CodeActionAutoApply.Never
        });
        return triggerCodeActionsForEditorSelection(editor, typeof userArgs?.kind === 'string'
            ? args.preferred
                ? ( localize(912, "No preferred source actions for '{0}' available", userArgs.kind))
                : ( localize(913, "No source actions for '{0}' available", userArgs.kind))
            : args.preferred
                ? ( localize(914, "No preferred source actions available"))
                : ( localize(915, "No source actions available")), {
            include: CodeActionKind.Source.contains(args.kind) ? args.kind : HierarchicalKind.None,
            includeSourceActions: true,
            onlyIncludePreferredActions: args.preferred,
        }, args.apply, CodeActionTriggerSource.SourceAction);
    }
}
class OrganizeImportsAction extends EditorAction {
    constructor() {
        super({
            id: organizeImportsCommandId,
            label: ( localize2(916, "Organize Imports")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                contextKeyForSupportedActions(CodeActionKind.SourceOrganizeImports)
            )),
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: KeyMod$1.Shift | KeyMod$1.Alt | KeyCode.KeyO,
                weight: KeybindingWeight.EditorContrib
            },
            metadata: {
                description: ( localize2(
                    917,
                    "Organize imports in the current file. Also called 'Optimize Imports' by some tools"
                ))
            }
        });
    }
    run(_accessor, editor) {
        return triggerCodeActionsForEditorSelection(editor, ( localize(918, "No organize imports action available")), { include: CodeActionKind.SourceOrganizeImports, includeSourceActions: true }, CodeActionAutoApply.IfSingle, CodeActionTriggerSource.OrganizeImports);
    }
}
class FixAllAction extends EditorAction {
    constructor() {
        super({
            id: fixAllCommandId,
            label: ( localize2(919, "Fix All")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                contextKeyForSupportedActions(CodeActionKind.SourceFixAll)
            ))
        });
    }
    run(_accessor, editor) {
        return triggerCodeActionsForEditorSelection(editor, ( localize(920, "No fix all action available")), { include: CodeActionKind.SourceFixAll, includeSourceActions: true }, CodeActionAutoApply.IfSingle, CodeActionTriggerSource.FixAll);
    }
}
class AutoFixAction extends EditorAction {
    constructor() {
        super({
            id: autoFixCommandId,
            label: ( localize2(921, "Auto Fix...")),
            precondition: ( ContextKeyExpr.and(
                EditorContextKeys.writable,
                contextKeyForSupportedActions(CodeActionKind.QuickFix)
            )),
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: KeyMod$1.Alt | KeyMod$1.Shift | KeyCode.Period,
                mac: {
                    primary: KeyMod$1.CtrlCmd | KeyMod$1.Alt | KeyCode.Period
                },
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
    run(_accessor, editor) {
        return triggerCodeActionsForEditorSelection(editor, ( localize(922, "No auto fixes available")), {
            include: CodeActionKind.QuickFix,
            onlyIncludePreferredActions: true
        }, CodeActionAutoApply.IfSingle, CodeActionTriggerSource.AutoFix);
    }
}

export { AutoFixAction, CodeActionCommand, FixAllAction, OrganizeImportsAction, QuickFixAction, RefactorAction, SourceAction };
