
import { isFirefox } from '../../../../base/browser/browser.js';
import { getActiveDocument } from '../../../../base/browser/dom.js';
import { KeyMod as KeyMod$1, KeyCode } from '../../../../base/common/keyCodes.js';
import { isNative, isWeb } from '../../../../base/common/platform.js';
import { localize, localize2 } from '../../../../nls.js';
import { MenuId, MenuRegistry } from '../../../../platform/actions/common/actions.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.service.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { CopyOptions, InMemoryClipboardMetadataManager } from '../../../browser/controller/editContext/clipboardUtils.js';
import { NativeEditContextRegistry } from '../../../browser/controller/editContext/native/nativeEditContextRegistry.js';
import { MultiCommand, EditorAction, registerEditorAction } from '../../../browser/editorExtensions.js';
import { ICodeEditorService } from '../../../browser/services/codeEditorService.service.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { Handler } from '../../../common/editorCommon.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { CopyPasteController } from '../../dropOrPasteInto/browser/copyPasteController.js';

const CLIPBOARD_CONTEXT_MENU_GROUP = '9_cutcopypaste';
const supportsCut = (isNative || document.queryCommandSupported('cut'));
const supportsCopy = (isNative || document.queryCommandSupported('copy'));
const supportsPaste = (typeof navigator.clipboard === 'undefined' || isFirefox) ? document.queryCommandSupported('paste') : true;
function registerCommand(command) {
    command.register();
    return command;
}
const CutAction = supportsCut ? registerCommand(( new MultiCommand({
    id: 'editor.action.clipboardCutAction',
    precondition: undefined,
    kbOpts: (
    (isNative ? {
        primary: KeyMod$1.CtrlCmd | KeyCode.KeyX,
        win: { primary: KeyMod$1.CtrlCmd | KeyCode.KeyX, secondary: [KeyMod$1.Shift | KeyCode.Delete] },
        weight: KeybindingWeight.EditorContrib
    } : undefined)),
    menuOpts: [{
            menuId: MenuId.MenubarEditMenu,
            group: '2_ccp',
            title: ( localize(884, "Cu&&t")),
            order: 1
        }, {
            menuId: MenuId.EditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(885, "Cut")),
            when: EditorContextKeys.writable,
            order: 1,
        }, {
            menuId: MenuId.CommandPalette,
            group: '',
            title: ( localize(885, "Cut")),
            order: 1
        }, {
            menuId: MenuId.SimpleEditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(885, "Cut")),
            when: EditorContextKeys.writable,
            order: 1,
        }]
}))) : undefined;
const CopyAction = supportsCopy ? registerCommand(( new MultiCommand({
    id: 'editor.action.clipboardCopyAction',
    precondition: undefined,
    kbOpts: (
    (isNative ? {
        primary: KeyMod$1.CtrlCmd | KeyCode.KeyC,
        win: { primary: KeyMod$1.CtrlCmd | KeyCode.KeyC, secondary: [KeyMod$1.CtrlCmd | KeyCode.Insert] },
        weight: KeybindingWeight.EditorContrib
    } : undefined)),
    menuOpts: [{
            menuId: MenuId.MenubarEditMenu,
            group: '2_ccp',
            title: ( localize(886, "&&Copy")),
            order: 2
        }, {
            menuId: MenuId.EditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(887, "Copy")),
            order: 2,
        }, {
            menuId: MenuId.CommandPalette,
            group: '',
            title: ( localize(887, "Copy")),
            order: 1
        }, {
            menuId: MenuId.SimpleEditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(887, "Copy")),
            order: 2,
        }]
}))) : undefined;
MenuRegistry.appendMenuItem(MenuId.MenubarEditMenu, { submenu: MenuId.MenubarCopy, title: ( localize2(888, "Copy As")), group: '2_ccp', order: 3 });
MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextCopy, title: ( localize2(888, "Copy As")), group: CLIPBOARD_CONTEXT_MENU_GROUP, order: 3 });
MenuRegistry.appendMenuItem(MenuId.EditorContext, { submenu: MenuId.EditorContextShare, title: ( localize2(889, "Share")), group: '11_share', order: -1, when: ( ContextKeyExpr.and(( ContextKeyExpr.notEquals('resourceScheme', 'output')), EditorContextKeys.editorTextFocus)) });
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { submenu: MenuId.ExplorerContextShare, title: ( localize2(889, "Share")), group: '11_share', order: -1 });
const PasteAction = supportsPaste ? registerCommand(( new MultiCommand({
    id: 'editor.action.clipboardPasteAction',
    precondition: undefined,
    kbOpts: (
    (isNative ? {
        primary: KeyMod$1.CtrlCmd | KeyCode.KeyV,
        win: { primary: KeyMod$1.CtrlCmd | KeyCode.KeyV, secondary: [KeyMod$1.Shift | KeyCode.Insert] },
        linux: { primary: KeyMod$1.CtrlCmd | KeyCode.KeyV, secondary: [KeyMod$1.Shift | KeyCode.Insert] },
        weight: KeybindingWeight.EditorContrib
    } : undefined)),
    menuOpts: [{
            menuId: MenuId.MenubarEditMenu,
            group: '2_ccp',
            title: ( localize(890, "&&Paste")),
            order: 4
        }, {
            menuId: MenuId.EditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(891, "Paste")),
            when: EditorContextKeys.writable,
            order: 4,
        }, {
            menuId: MenuId.CommandPalette,
            group: '',
            title: ( localize(891, "Paste")),
            order: 1
        }, {
            menuId: MenuId.SimpleEditorContext,
            group: CLIPBOARD_CONTEXT_MENU_GROUP,
            title: ( localize(891, "Paste")),
            when: EditorContextKeys.writable,
            order: 4,
        }]
}))) : undefined;
class ExecCommandCopyWithSyntaxHighlightingAction extends EditorAction {
    constructor() {
        super({
            id: 'editor.action.clipboardCopyWithSyntaxHighlightingAction',
            label: ( localize2(892, "Copy with Syntax Highlighting")),
            precondition: undefined,
            kbOpts: {
                kbExpr: EditorContextKeys.textInputFocus,
                primary: 0,
                weight: KeybindingWeight.EditorContrib
            }
        });
    }
    run(accessor, editor) {
        if (!editor.hasModel()) {
            return;
        }
        const emptySelectionClipboard = editor.getOption(EditorOption.emptySelectionClipboard);
        if (!emptySelectionClipboard && editor.getSelection().isEmpty()) {
            return;
        }
        CopyOptions.forceCopyWithSyntaxHighlighting = true;
        editor.focus();
        editor.getContainerDomNode().ownerDocument.execCommand('copy');
        CopyOptions.forceCopyWithSyntaxHighlighting = false;
    }
}
function registerExecCommandImpl(target, browserCommand) {
    if (!target) {
        return;
    }
    target.addImplementation(10000, 'code-editor', (accessor, args) => {
        const focusedEditor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
        if (focusedEditor && focusedEditor.hasTextFocus()) {
            const emptySelectionClipboard = focusedEditor.getOption(EditorOption.emptySelectionClipboard);
            const selection = focusedEditor.getSelection();
            if (selection && selection.isEmpty() && !emptySelectionClipboard) {
                return true;
            }
            if (focusedEditor.getOption(EditorOption.effectiveExperimentalEditContextEnabled) && browserCommand === 'cut') {
                focusedEditor.getContainerDomNode().ownerDocument.execCommand('copy');
                focusedEditor.trigger(undefined, Handler.Cut, undefined);
            }
            else {
                focusedEditor.getContainerDomNode().ownerDocument.execCommand(browserCommand);
            }
            return true;
        }
        return false;
    });
    target.addImplementation(0, 'generic-dom', (accessor, args) => {
        getActiveDocument().execCommand(browserCommand);
        return true;
    });
}
registerExecCommandImpl(CutAction, 'cut');
registerExecCommandImpl(CopyAction, 'copy');
if (PasteAction) {
    PasteAction.addImplementation(10000, 'code-editor', (accessor, args) => {
        const codeEditorService = accessor.get(ICodeEditorService);
        const clipboardService = accessor.get(IClipboardService);
        const focusedEditor = codeEditorService.getFocusedCodeEditor();
        if (focusedEditor && focusedEditor.hasModel() && focusedEditor.hasTextFocus()) {
            let result;
            const experimentalEditContextEnabled = focusedEditor.getOption(EditorOption.effectiveExperimentalEditContextEnabled);
            if (experimentalEditContextEnabled) {
                const nativeEditContext = NativeEditContextRegistry.get(focusedEditor.getId());
                if (nativeEditContext) {
                    result = nativeEditContext.executePaste();
                }
                else {
                    result = false;
                }
            }
            else {
                result = focusedEditor.getContainerDomNode().ownerDocument.execCommand('paste');
            }
            if (result) {
                return CopyPasteController.get(focusedEditor)?.finishedPaste() ?? Promise.resolve();
            }
            else if (isWeb) {
                return (async () => {
                    const clipboardText = await clipboardService.readText();
                    if (clipboardText !== '') {
                        const metadata = InMemoryClipboardMetadataManager.INSTANCE.get(clipboardText);
                        let pasteOnNewLine = false;
                        let multicursorText = null;
                        let mode = null;
                        if (metadata) {
                            pasteOnNewLine = (focusedEditor.getOption(EditorOption.emptySelectionClipboard) && !!metadata.isFromEmptySelection);
                            multicursorText = (typeof metadata.multicursorText !== 'undefined' ? metadata.multicursorText : null);
                            mode = metadata.mode;
                        }
                        focusedEditor.trigger('keyboard', Handler.Paste, {
                            text: clipboardText,
                            pasteOnNewLine,
                            multicursorText,
                            mode
                        });
                    }
                })();
            }
            return true;
        }
        return false;
    });
    PasteAction.addImplementation(0, 'generic-dom', (accessor, args) => {
        getActiveDocument().execCommand('paste');
        return true;
    });
}
if (supportsCopy) {
    registerEditorAction(ExecCommandCopyWithSyntaxHighlightingAction);
}

export { CopyAction, CutAction, PasteAction };
