import { localizeWithPath, localize2WithPath } from '../../../../nls.js';
import { KeyMod as KeyMod$1, KeyCode } from '../../../../base/common/keyCodes.js';
import { List } from '../../../../base/browser/ui/list/listWidget.js';
import { KeybindingsRegistry, KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { IListService } from '../../../../platform/list/browser/listService.service.js';
import { CONTEXT_DISASSEMBLY_VIEW_FOCUS, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_IN_DEBUG_REPL, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_STATE, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, REPL_VIEW_ID, State, CONTEXT_DEBUGGERS_AVAILABLE, getStateLabel, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_INPUT_FOCUSED, VIEWLET_ID as VIEWLET_ID$1, isFrameDeemphasized, EDITOR_CONTRIBUTION_ID } from '../common/debug.js';
import { IDebugService } from '../common/debug.service.js';
import { Expression, Variable, Breakpoint, FunctionBreakpoint, DataBreakpoint } from '../common/debugModel.js';
import { VIEWLET_ID } from '../../extensions/common/extensions.js';
import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
import { MenuRegistry, MenuId, registerAction2, Action2 } from '../../../../platform/actions/common/actions.js';
import { IEditorService } from '../../../services/editor/common/editorService.service.js';
import { EditorContextKeys } from '../../../../editor/common/editorContextKeys.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { openBreakpointSource } from './breakpointsView.js';
import { INotificationService } from '../../../../platform/notification/common/notification.service.js';
import { InputFocusedContext } from '../../../../platform/contextkey/common/contextkeys.js';
import { PanelFocusContext, ResourceContextKey, ActiveEditorContext } from '../../../common/contextkeys.js';
import { CommandsRegistry } from '../../../../platform/commands/common/commands.js';
import { ICommandService } from '../../../../platform/commands/common/commands.service.js';
import { ITextResourcePropertiesService } from '../../../../editor/common/services/textResourceConfiguration.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.service.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.service.js';
import { ViewContainerLocation } from '../../../common/views.js';
import { IViewsService } from '../../../services/views/common/viewsService.service.js';
import { deepClone } from '../../../../base/common/objects.js';
import { isWeb, isWindows } from '../../../../base/common/platform.js';
import { saveAllBeforeDebugStart } from '../common/debugUtils.js';
import { IPaneCompositePartService } from '../../../services/panecomposite/browser/panecomposite.service.js';
import { showLoadedScriptMenu } from '../common/loadedScriptsPicker.js';
import { showDebugSessionMenu } from './debugSessionPicker.js';
import { TEXT_FILE_EDITOR_ID } from '../../files/common/files.js';
const _moduleId = "vs/workbench/contrib/debug/browser/debugCommands";
const ADD_CONFIGURATION_ID = 'debug.addConfiguration';
const TOGGLE_INLINE_BREAKPOINT_ID = 'editor.debug.action.toggleInlineBreakpoint';
const COPY_STACK_TRACE_ID = 'debug.copyStackTrace';
const REVERSE_CONTINUE_ID = 'workbench.action.debug.reverseContinue';
const STEP_BACK_ID = 'workbench.action.debug.stepBack';
const RESTART_SESSION_ID = 'workbench.action.debug.restart';
const TERMINATE_THREAD_ID = 'workbench.action.debug.terminateThread';
const STEP_OVER_ID = 'workbench.action.debug.stepOver';
const STEP_INTO_ID = 'workbench.action.debug.stepInto';
const STEP_INTO_TARGET_ID = 'workbench.action.debug.stepIntoTarget';
const STEP_OUT_ID = 'workbench.action.debug.stepOut';
const PAUSE_ID = 'workbench.action.debug.pause';
const DISCONNECT_ID = 'workbench.action.debug.disconnect';
const DISCONNECT_AND_SUSPEND_ID = 'workbench.action.debug.disconnectAndSuspend';
const STOP_ID = 'workbench.action.debug.stop';
const RESTART_FRAME_ID = 'workbench.action.debug.restartFrame';
const CONTINUE_ID = 'workbench.action.debug.continue';
const FOCUS_REPL_ID = 'workbench.debug.action.focusRepl';
const JUMP_TO_CURSOR_ID = 'debug.jumpToCursor';
const FOCUS_SESSION_ID = 'workbench.action.debug.focusProcess';
const SELECT_AND_START_ID = 'workbench.action.debug.selectandstart';
const SELECT_DEBUG_CONSOLE_ID = 'workbench.action.debug.selectDebugConsole';
const SELECT_DEBUG_SESSION_ID = 'workbench.action.debug.selectDebugSession';
const DEBUG_CONFIGURE_COMMAND_ID = 'workbench.action.debug.configure';
const DEBUG_START_COMMAND_ID = 'workbench.action.debug.start';
const DEBUG_RUN_COMMAND_ID = 'workbench.action.debug.run';
const EDIT_EXPRESSION_COMMAND_ID = 'debug.renameWatchExpression';
const SET_EXPRESSION_COMMAND_ID = 'debug.setWatchExpression';
const REMOVE_EXPRESSION_COMMAND_ID = 'debug.removeWatchExpression';
const NEXT_DEBUG_CONSOLE_ID = 'workbench.action.debug.nextConsole';
const PREV_DEBUG_CONSOLE_ID = 'workbench.action.debug.prevConsole';
const SHOW_LOADED_SCRIPTS_ID = 'workbench.action.debug.showLoadedScripts';
const CALLSTACK_TOP_ID = 'workbench.action.debug.callStackTop';
const CALLSTACK_BOTTOM_ID = 'workbench.action.debug.callStackBottom';
const CALLSTACK_UP_ID = 'workbench.action.debug.callStackUp';
const CALLSTACK_DOWN_ID = 'workbench.action.debug.callStackDown';
const ADD_TO_WATCH_ID = 'debug.addToWatchExpressions';
const COPY_EVALUATE_PATH_ID = 'debug.copyEvaluatePath';
const COPY_VALUE_ID = 'workbench.debug.viewlet.action.copyValue';
const DEBUG_COMMAND_CATEGORY = ( localize2WithPath(_moduleId, 0, 'Debug'));
const RESTART_LABEL = ( localize2WithPath(_moduleId, 1, "Restart"));
const STEP_OVER_LABEL = ( localize2WithPath(_moduleId, 2, "Step Over"));
const STEP_INTO_LABEL = ( localize2WithPath(_moduleId, 3, "Step Into"));
const STEP_INTO_TARGET_LABEL = ( localize2WithPath(_moduleId, 4, "Step Into Target"));
const STEP_OUT_LABEL = ( localize2WithPath(_moduleId, 5, "Step Out"));
const PAUSE_LABEL = ( localize2WithPath(_moduleId, 6, "Pause"));
const DISCONNECT_LABEL = ( localize2WithPath(_moduleId, 7, "Disconnect"));
const DISCONNECT_AND_SUSPEND_LABEL = ( localize2WithPath(_moduleId, 8, "Disconnect and Suspend"));
const STOP_LABEL = ( localize2WithPath(_moduleId, 9, "Stop"));
const CONTINUE_LABEL = ( localize2WithPath(_moduleId, 10, "Continue"));
const FOCUS_SESSION_LABEL = ( localize2WithPath(_moduleId, 11, "Focus Session"));
const SELECT_AND_START_LABEL = ( localize2WithPath(_moduleId, 12, "Select and Start Debugging"));
const DEBUG_CONFIGURE_LABEL = ( localizeWithPath(_moduleId, 13, "Open '{0}'", 'launch.json'));
const DEBUG_START_LABEL = ( localize2WithPath(_moduleId, 14, "Start Debugging"));
const DEBUG_RUN_LABEL = ( localize2WithPath(_moduleId, 15, "Start Without Debugging"));
const NEXT_DEBUG_CONSOLE_LABEL = ( localize2WithPath(_moduleId, 16, "Focus Next Debug Console"));
const PREV_DEBUG_CONSOLE_LABEL = ( localize2WithPath(_moduleId, 17, "Focus Previous Debug Console"));
const OPEN_LOADED_SCRIPTS_LABEL = ( localize2WithPath(_moduleId, 18, "Open Loaded Script..."));
const CALLSTACK_TOP_LABEL = ( localize2WithPath(_moduleId, 19, "Navigate to Top of Call Stack"));
const CALLSTACK_BOTTOM_LABEL = ( localize2WithPath(_moduleId, 20, "Navigate to Bottom of Call Stack"));
const CALLSTACK_UP_LABEL = ( localize2WithPath(_moduleId, 21, "Navigate Up Call Stack"));
const CALLSTACK_DOWN_LABEL = ( localize2WithPath(_moduleId, 22, "Navigate Down Call Stack"));
const COPY_EVALUATE_PATH_LABEL = ( localize2WithPath(_moduleId, 23, "Copy as Expression"));
const COPY_VALUE_LABEL = ( localize2WithPath(_moduleId, 24, "Copy Value"));
const ADD_TO_WATCH_LABEL = ( localize2WithPath(_moduleId, 25, "Add to Watch"));
const SELECT_DEBUG_CONSOLE_LABEL = ( localize2WithPath(_moduleId, 26, "Select Debug Console"));
const SELECT_DEBUG_SESSION_LABEL = ( localize2WithPath(_moduleId, 27, "Select Debug Session"));
const DEBUG_QUICK_ACCESS_PREFIX = 'debug ';
const DEBUG_CONSOLE_QUICK_ACCESS_PREFIX = 'debug consoles ';
function isThreadContext(obj) {
    return obj && typeof obj.sessionId === 'string' && typeof obj.threadId === 'string';
}
async function getThreadAndRun(accessor, sessionAndThreadId, run) {
    const debugService = accessor.get(IDebugService);
    let thread;
    if (isThreadContext(sessionAndThreadId)) {
        const session = debugService.getModel().getSession(sessionAndThreadId.sessionId);
        if (session) {
            thread = session.getAllThreads().find(t => t.getId() === sessionAndThreadId.threadId);
        }
    }
    else if (isSessionContext(sessionAndThreadId)) {
        const session = debugService.getModel().getSession(sessionAndThreadId.sessionId);
        if (session) {
            const threads = session.getAllThreads();
            thread = threads.length > 0 ? threads[0] : undefined;
        }
    }
    if (!thread) {
        thread = debugService.getViewModel().focusedThread;
        if (!thread) {
            const focusedSession = debugService.getViewModel().focusedSession;
            const threads = focusedSession ? focusedSession.getAllThreads() : undefined;
            thread = threads && threads.length ? threads[0] : undefined;
        }
    }
    if (thread) {
        await run(thread);
    }
}
function isStackFrameContext(obj) {
    return obj && typeof obj.sessionId === 'string' && typeof obj.threadId === 'string' && typeof obj.frameId === 'string';
}
function getFrame(debugService, context) {
    if (isStackFrameContext(context)) {
        const session = debugService.getModel().getSession(context.sessionId);
        if (session) {
            const thread = session.getAllThreads().find(t => t.getId() === context.threadId);
            if (thread) {
                return thread.getCallStack().find(sf => sf.getId() === context.frameId);
            }
        }
    }
    else {
        return debugService.getViewModel().focusedStackFrame;
    }
    return undefined;
}
function isSessionContext(obj) {
    return obj && typeof obj.sessionId === 'string';
}
async function changeDebugConsoleFocus(accessor, next) {
    const debugService = accessor.get(IDebugService);
    const viewsService = accessor.get(IViewsService);
    const sessions = debugService.getModel().getSessions(true).filter(s => s.hasSeparateRepl());
    let currSession = debugService.getViewModel().focusedSession;
    let nextIndex = 0;
    if (sessions.length > 0 && currSession) {
        while (currSession && !currSession.hasSeparateRepl()) {
            currSession = currSession.parentSession;
        }
        if (currSession) {
            const currIndex = sessions.indexOf(currSession);
            if (next) {
                nextIndex = (currIndex === (sessions.length - 1) ? 0 : (currIndex + 1));
            }
            else {
                nextIndex = (currIndex === 0 ? (sessions.length - 1) : (currIndex - 1));
            }
        }
    }
    await debugService.focusStackFrame(undefined, undefined, sessions[nextIndex], { explicit: true });
    if (!viewsService.isViewVisible(REPL_VIEW_ID)) {
        await viewsService.openView(REPL_VIEW_ID, true);
    }
}
async function navigateCallStack(debugService, down) {
    const frame = debugService.getViewModel().focusedStackFrame;
    if (frame) {
        let callStack = frame.thread.getCallStack();
        let index = callStack.findIndex(elem => elem.frameId === frame.frameId);
        let nextVisibleFrame;
        if (down) {
            if (index >= callStack.length - 1) {
                if (frame.thread.reachedEndOfCallStack) {
                    goToTopOfCallStack(debugService);
                    return;
                }
                else {
                    await debugService.getModel().fetchCallstack(frame.thread, 20);
                    callStack = frame.thread.getCallStack();
                    index = callStack.findIndex(elem => elem.frameId === frame.frameId);
                }
            }
            nextVisibleFrame = findNextVisibleFrame(true, callStack, index);
        }
        else {
            if (index <= 0) {
                goToBottomOfCallStack(debugService);
                return;
            }
            nextVisibleFrame = findNextVisibleFrame(false, callStack, index);
        }
        if (nextVisibleFrame) {
            debugService.focusStackFrame(nextVisibleFrame, undefined, undefined, { preserveFocus: false });
        }
    }
}
async function goToBottomOfCallStack(debugService) {
    const thread = debugService.getViewModel().focusedThread;
    if (thread) {
        await debugService.getModel().fetchCallstack(thread);
        const callStack = thread.getCallStack();
        if (callStack.length > 0) {
            const nextVisibleFrame = findNextVisibleFrame(false, callStack, 0);
            if (nextVisibleFrame) {
                debugService.focusStackFrame(nextVisibleFrame, undefined, undefined, { preserveFocus: false });
            }
        }
    }
}
function goToTopOfCallStack(debugService) {
    const thread = debugService.getViewModel().focusedThread;
    if (thread) {
        debugService.focusStackFrame(thread.getTopStackFrame(), undefined, undefined, { preserveFocus: false });
    }
}
function findNextVisibleFrame(down, callStack, startIndex) {
    if (startIndex >= callStack.length) {
        startIndex = callStack.length - 1;
    }
    else if (startIndex < 0) {
        startIndex = 0;
    }
    let index = startIndex;
    let currFrame;
    do {
        if (down) {
            if (index === callStack.length - 1) {
                index = 0;
            }
            else {
                index++;
            }
        }
        else {
            if (index === 0) {
                index = callStack.length - 1;
            }
            else {
                index--;
            }
        }
        currFrame = callStack[index];
        if (!isFrameDeemphasized(currFrame)) {
            return currFrame;
        }
    } while (index !== startIndex);
    return undefined;
}
CommandsRegistry.registerCommand({
    id: COPY_STACK_TRACE_ID,
    handler: async (accessor, _, context) => {
        const textResourcePropertiesService = accessor.get(ITextResourcePropertiesService);
        const clipboardService = accessor.get(IClipboardService);
        const debugService = accessor.get(IDebugService);
        const frame = getFrame(debugService, context);
        if (frame) {
            const eol = textResourcePropertiesService.getEOL(frame.source.uri);
            await clipboardService.writeText(( (frame.thread.getCallStack().map(sf => ( (sf.toString()))))).join(eol));
        }
    }
});
CommandsRegistry.registerCommand({
    id: REVERSE_CONTINUE_ID,
    handler: async (accessor, _, context) => {
        await getThreadAndRun(accessor, context, thread => thread.reverseContinue());
    }
});
CommandsRegistry.registerCommand({
    id: STEP_BACK_ID,
    handler: async (accessor, _, context) => {
        const contextKeyService = accessor.get(IContextKeyService);
        if (CONTEXT_DISASSEMBLY_VIEW_FOCUS.getValue(contextKeyService)) {
            await getThreadAndRun(accessor, context, (thread) => thread.stepBack('instruction'));
        }
        else {
            await getThreadAndRun(accessor, context, (thread) => thread.stepBack());
        }
    }
});
CommandsRegistry.registerCommand({
    id: TERMINATE_THREAD_ID,
    handler: async (accessor, _, context) => {
        await getThreadAndRun(accessor, context, thread => thread.terminate());
    }
});
CommandsRegistry.registerCommand({
    id: JUMP_TO_CURSOR_ID,
    handler: async (accessor) => {
        const debugService = accessor.get(IDebugService);
        const stackFrame = debugService.getViewModel().focusedStackFrame;
        const editorService = accessor.get(IEditorService);
        const activeEditorControl = editorService.activeTextEditorControl;
        const notificationService = accessor.get(INotificationService);
        const quickInputService = accessor.get(IQuickInputService);
        if (stackFrame && isCodeEditor(activeEditorControl) && activeEditorControl.hasModel()) {
            const position = activeEditorControl.getPosition();
            const resource = activeEditorControl.getModel().uri;
            const source = stackFrame.thread.session.getSourceForUri(resource);
            if (source) {
                const response = await stackFrame.thread.session.gotoTargets(source.raw, position.lineNumber, position.column);
                const targets = response?.body.targets;
                if (targets && targets.length) {
                    let id = targets[0].id;
                    if (targets.length > 1) {
                        const picks = ( (targets.map(t => ({ label: t.label, _id: t.id }))));
                        const pick = await quickInputService.pick(picks, { placeHolder: ( localizeWithPath(_moduleId, 28, "Choose the specific location")) });
                        if (!pick) {
                            return;
                        }
                        id = pick._id;
                    }
                    return await stackFrame.thread.session.goto(stackFrame.thread.threadId, id).catch(e => notificationService.warn(e));
                }
            }
        }
        return notificationService.warn(( localizeWithPath(
            _moduleId,
            29,
            "No executable code is associated at the current cursor position."
        )));
    }
});
CommandsRegistry.registerCommand({
    id: CALLSTACK_TOP_ID,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        goToTopOfCallStack(debugService);
    }
});
CommandsRegistry.registerCommand({
    id: CALLSTACK_BOTTOM_ID,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        await goToBottomOfCallStack(debugService);
    }
});
CommandsRegistry.registerCommand({
    id: CALLSTACK_UP_ID,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        navigateCallStack(debugService, false);
    }
});
CommandsRegistry.registerCommand({
    id: CALLSTACK_DOWN_ID,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        navigateCallStack(debugService, true);
    }
});
MenuRegistry.appendMenuItem(MenuId.EditorContext, {
    command: {
        id: JUMP_TO_CURSOR_ID,
        title: ( localizeWithPath(_moduleId, 30, "Jump to Cursor")),
        category: DEBUG_COMMAND_CATEGORY
    },
    when: ( (ContextKeyExpr.and(CONTEXT_JUMP_TO_CURSOR_SUPPORTED, EditorContextKeys.editorTextFocus))),
    group: 'debug',
    order: 3
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: NEXT_DEBUG_CONSOLE_ID,
    weight: KeybindingWeight.WorkbenchContrib + 1,
    when: CONTEXT_IN_DEBUG_REPL,
    primary: KeyMod$1.CtrlCmd | KeyCode.PageDown,
    mac: { primary: KeyMod$1.Shift | KeyMod$1.CtrlCmd | KeyCode.BracketRight },
    handler: async (accessor, _, context) => {
        changeDebugConsoleFocus(accessor, true);
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: PREV_DEBUG_CONSOLE_ID,
    weight: KeybindingWeight.WorkbenchContrib + 1,
    when: CONTEXT_IN_DEBUG_REPL,
    primary: KeyMod$1.CtrlCmd | KeyCode.PageUp,
    mac: { primary: KeyMod$1.Shift | KeyMod$1.CtrlCmd | KeyCode.BracketLeft },
    handler: async (accessor, _, context) => {
        changeDebugConsoleFocus(accessor, false);
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: RESTART_SESSION_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.Shift | KeyMod$1.CtrlCmd | KeyCode.F5,
    when: CONTEXT_IN_DEBUG_MODE,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        const configurationService = accessor.get(IConfigurationService);
        let session;
        if (isSessionContext(context)) {
            session = debugService.getModel().getSession(context.sessionId);
        }
        else {
            session = debugService.getViewModel().focusedSession;
        }
        if (!session) {
            const { launch, name } = debugService.getConfigurationManager().selectedConfiguration;
            await debugService.startDebugging(launch, name, { noDebug: false, startedByUser: true });
        }
        else {
            const showSubSessions = configurationService.getValue('debug').showSubSessionsInToolBar;
            while (!showSubSessions && session.lifecycleManagedByParent && session.parentSession) {
                session = session.parentSession;
            }
            session.removeReplExpressions();
            await debugService.restartSession(session);
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: STEP_OVER_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyCode.F10,
    when: ( (CONTEXT_DEBUG_STATE.isEqualTo('stopped'))),
    handler: async (accessor, _, context) => {
        const contextKeyService = accessor.get(IContextKeyService);
        if (CONTEXT_DISASSEMBLY_VIEW_FOCUS.getValue(contextKeyService)) {
            await getThreadAndRun(accessor, context, (thread) => thread.next('instruction'));
        }
        else {
            await getThreadAndRun(accessor, context, (thread) => thread.next());
        }
    }
});
const STEP_INTO_KEYBINDING = (isWeb && isWindows) ? (KeyMod$1.Alt | KeyCode.F11) : KeyCode.F11;
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: STEP_INTO_ID,
    weight: KeybindingWeight.WorkbenchContrib + 10,
    primary: STEP_INTO_KEYBINDING,
    when: ( (CONTEXT_DEBUG_STATE.notEqualsTo('inactive'))),
    handler: async (accessor, _, context) => {
        const contextKeyService = accessor.get(IContextKeyService);
        if (CONTEXT_DISASSEMBLY_VIEW_FOCUS.getValue(contextKeyService)) {
            await getThreadAndRun(accessor, context, (thread) => thread.stepIn('instruction'));
        }
        else {
            await getThreadAndRun(accessor, context, (thread) => thread.stepIn());
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: STEP_OUT_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.Shift | KeyCode.F11,
    when: ( (CONTEXT_DEBUG_STATE.isEqualTo('stopped'))),
    handler: async (accessor, _, context) => {
        const contextKeyService = accessor.get(IContextKeyService);
        if (CONTEXT_DISASSEMBLY_VIEW_FOCUS.getValue(contextKeyService)) {
            await getThreadAndRun(accessor, context, (thread) => thread.stepOut('instruction'));
        }
        else {
            await getThreadAndRun(accessor, context, (thread) => thread.stepOut());
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: PAUSE_ID,
    weight: KeybindingWeight.WorkbenchContrib + 2,
    primary: KeyCode.F6,
    when: ( (CONTEXT_DEBUG_STATE.isEqualTo('running'))),
    handler: async (accessor, _, context) => {
        await getThreadAndRun(accessor, context, thread => thread.pause());
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: STEP_INTO_TARGET_ID,
    primary: STEP_INTO_KEYBINDING | KeyMod$1.CtrlCmd,
    when: ( (ContextKeyExpr.and(
        CONTEXT_STEP_INTO_TARGETS_SUPPORTED,
        CONTEXT_IN_DEBUG_MODE,
         (CONTEXT_DEBUG_STATE.isEqualTo('stopped'))
    ))),
    weight: KeybindingWeight.WorkbenchContrib,
    handler: async (accessor, _, context) => {
        const quickInputService = accessor.get(IQuickInputService);
        const debugService = accessor.get(IDebugService);
        const session = debugService.getViewModel().focusedSession;
        const frame = debugService.getViewModel().focusedStackFrame;
        if (!frame || !session) {
            return;
        }
        const editor = await accessor.get(IEditorService).openEditor({
            resource: frame.source.uri,
            options: { revealIfOpened: true }
        });
        let codeEditor;
        if (editor) {
            const ctrl = editor?.getControl();
            if (isCodeEditor(ctrl)) {
                codeEditor = ctrl;
            }
        }
        const qp = quickInputService.createQuickPick();
        qp.busy = true;
        qp.show();
        qp.onDidChangeActive(([item]) => {
            if (codeEditor && item && item.target.line !== undefined) {
                codeEditor.revealLineInCenterIfOutsideViewport(item.target.line);
                codeEditor.setSelection({
                    startLineNumber: item.target.line,
                    startColumn: item.target.column || 1,
                    endLineNumber: item.target.endLine || item.target.line,
                    endColumn: item.target.endColumn || item.target.column || 1,
                });
            }
        });
        qp.onDidAccept(() => {
            if (qp.activeItems.length) {
                session.stepIn(frame.thread.threadId, qp.activeItems[0].target.id);
            }
        });
        qp.onDidHide(() => qp.dispose());
        session.stepInTargets(frame.frameId).then(targets => {
            qp.busy = false;
            if (targets?.length) {
                qp.items = targets?.map(target => ({ target, label: target.label }));
            }
            else {
                qp.placeholder = ( localizeWithPath(_moduleId, 31, "No step targets available"));
            }
        });
    }
});
async function stopHandler(accessor, _, context, disconnect, suspend) {
    const debugService = accessor.get(IDebugService);
    let session;
    if (isSessionContext(context)) {
        session = debugService.getModel().getSession(context.sessionId);
    }
    else {
        session = debugService.getViewModel().focusedSession;
    }
    const configurationService = accessor.get(IConfigurationService);
    const showSubSessions = configurationService.getValue('debug').showSubSessionsInToolBar;
    while (!showSubSessions && session && session.lifecycleManagedByParent && session.parentSession) {
        session = session.parentSession;
    }
    await debugService.stopSession(session, disconnect, suspend);
}
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: DISCONNECT_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.Shift | KeyCode.F5,
    when: ( (ContextKeyExpr.and(CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_IN_DEBUG_MODE))),
    handler: (accessor, _, context) => stopHandler(accessor, _, context, true)
});
CommandsRegistry.registerCommand({
    id: DISCONNECT_AND_SUSPEND_ID,
    handler: (accessor, _, context) => stopHandler(accessor, _, context, true, true)
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: STOP_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.Shift | KeyCode.F5,
    when: ( (ContextKeyExpr.and(
         (CONTEXT_FOCUSED_SESSION_IS_ATTACH.toNegated()),
        CONTEXT_IN_DEBUG_MODE
    ))),
    handler: (accessor, _, context) => stopHandler(accessor, _, context, false)
});
CommandsRegistry.registerCommand({
    id: RESTART_FRAME_ID,
    handler: async (accessor, _, context) => {
        const debugService = accessor.get(IDebugService);
        const notificationService = accessor.get(INotificationService);
        const frame = getFrame(debugService, context);
        if (frame) {
            try {
                await frame.restart();
            }
            catch (e) {
                notificationService.error(e);
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: CONTINUE_ID,
    weight: KeybindingWeight.WorkbenchContrib + 10,
    primary: KeyCode.F5,
    when: ( (CONTEXT_DEBUG_STATE.isEqualTo('stopped'))),
    handler: async (accessor, _, context) => {
        await getThreadAndRun(accessor, context, thread => thread.continue());
    }
});
CommandsRegistry.registerCommand({
    id: SHOW_LOADED_SCRIPTS_ID,
    handler: async (accessor) => {
        await showLoadedScriptMenu(accessor);
    }
});
CommandsRegistry.registerCommand({
    id: FOCUS_REPL_ID,
    handler: async (accessor) => {
        const viewsService = accessor.get(IViewsService);
        await viewsService.openView(REPL_VIEW_ID, true);
    }
});
CommandsRegistry.registerCommand({
    id: 'debug.startFromConfig',
    handler: async (accessor, config) => {
        const debugService = accessor.get(IDebugService);
        await debugService.startDebugging(undefined, config);
    }
});
CommandsRegistry.registerCommand({
    id: FOCUS_SESSION_ID,
    handler: async (accessor, session) => {
        const debugService = accessor.get(IDebugService);
        const editorService = accessor.get(IEditorService);
        const stoppedChildSession = debugService.getModel().getSessions().find(s => s.parentSession === session && s.state === State.Stopped);
        if (stoppedChildSession && session.state !== State.Stopped) {
            session = stoppedChildSession;
        }
        await debugService.focusStackFrame(undefined, undefined, session, { explicit: true });
        const stackFrame = debugService.getViewModel().focusedStackFrame;
        if (stackFrame) {
            await stackFrame.openInEditor(editorService, true);
        }
    }
});
CommandsRegistry.registerCommand({
    id: SELECT_AND_START_ID,
    handler: async (accessor, debugType, debugStartOptions) => {
        const quickInputService = accessor.get(IQuickInputService);
        const debugService = accessor.get(IDebugService);
        if (debugType) {
            const configManager = debugService.getConfigurationManager();
            const dynamicProviders = await configManager.getDynamicProviders();
            for (const provider of dynamicProviders) {
                if (provider.type === debugType) {
                    const pick = await provider.pick();
                    if (pick) {
                        await configManager.selectConfiguration(pick.launch, pick.config.name, pick.config, { type: provider.type });
                        debugService.startDebugging(pick.launch, pick.config, { noDebug: debugStartOptions?.noDebug, startedByUser: true });
                        return;
                    }
                }
            }
        }
        quickInputService.quickAccess.show(DEBUG_QUICK_ACCESS_PREFIX);
    }
});
CommandsRegistry.registerCommand({
    id: SELECT_DEBUG_CONSOLE_ID,
    handler: async (accessor) => {
        const quickInputService = accessor.get(IQuickInputService);
        quickInputService.quickAccess.show(DEBUG_CONSOLE_QUICK_ACCESS_PREFIX);
    }
});
CommandsRegistry.registerCommand({
    id: SELECT_DEBUG_SESSION_ID,
    handler: async (accessor) => {
        showDebugSessionMenu(accessor, SELECT_AND_START_ID);
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: DEBUG_START_COMMAND_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyCode.F5,
    when: ( (ContextKeyExpr.and(
        CONTEXT_DEBUGGERS_AVAILABLE,
         (CONTEXT_DEBUG_STATE.isEqualTo('inactive'))
    ))),
    handler: async (accessor, debugStartOptions) => {
        const debugService = accessor.get(IDebugService);
        await saveAllBeforeDebugStart(accessor.get(IConfigurationService), accessor.get(IEditorService));
        const { launch, name, getConfig } = debugService.getConfigurationManager().selectedConfiguration;
        const config = await getConfig();
        const configOrName = config ? Object.assign(deepClone(config), debugStartOptions?.config) : name;
        await debugService.startDebugging(launch, configOrName, { noDebug: debugStartOptions?.noDebug, startedByUser: true }, false);
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: DEBUG_RUN_COMMAND_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.CtrlCmd | KeyCode.F5,
    mac: { primary: KeyMod$1.WinCtrl | KeyCode.F5 },
    when: ( (ContextKeyExpr.and(
        CONTEXT_DEBUGGERS_AVAILABLE,
         (CONTEXT_DEBUG_STATE.notEqualsTo(getStateLabel(State.Initializing)))
    ))),
    handler: async (accessor) => {
        const commandService = accessor.get(ICommandService);
        await commandService.executeCommand(DEBUG_START_COMMAND_ID, { noDebug: true });
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.toggleBreakpoint',
    weight: KeybindingWeight.WorkbenchContrib + 5,
    when: ( (ContextKeyExpr.and(
        CONTEXT_BREAKPOINTS_FOCUSED,
         (InputFocusedContext.toNegated())
    ))),
    primary: KeyCode.Space,
    handler: (accessor) => {
        const listService = accessor.get(IListService);
        const debugService = accessor.get(IDebugService);
        const list = listService.lastFocusedList;
        if (list instanceof List) {
            const focused = list.getFocusedElements();
            if (focused && focused.length) {
                debugService.enableOrDisableBreakpoints(!focused[0].enabled, focused[0]);
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.enableOrDisableBreakpoint',
    weight: KeybindingWeight.WorkbenchContrib,
    primary: undefined,
    when: EditorContextKeys.editorTextFocus,
    handler: (accessor) => {
        const debugService = accessor.get(IDebugService);
        const editorService = accessor.get(IEditorService);
        const control = editorService.activeTextEditorControl;
        if (isCodeEditor(control)) {
            const model = control.getModel();
            if (model) {
                const position = control.getPosition();
                if (position) {
                    const bps = debugService.getModel().getBreakpoints({ uri: model.uri, lineNumber: position.lineNumber });
                    if (bps.length) {
                        debugService.enableOrDisableBreakpoints(!bps[0].enabled, bps[0]);
                    }
                }
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: EDIT_EXPRESSION_COMMAND_ID,
    weight: KeybindingWeight.WorkbenchContrib + 5,
    when: CONTEXT_WATCH_EXPRESSIONS_FOCUSED,
    primary: KeyCode.F2,
    mac: { primary: KeyCode.Enter },
    handler: (accessor, expression) => {
        const debugService = accessor.get(IDebugService);
        if (!(expression instanceof Expression)) {
            const listService = accessor.get(IListService);
            const focused = listService.lastFocusedList;
            if (focused) {
                const elements = focused.getFocus();
                if (Array.isArray(elements) && elements[0] instanceof Expression) {
                    expression = elements[0];
                }
            }
        }
        if (expression instanceof Expression) {
            debugService.getViewModel().setSelectedExpression(expression, false);
        }
    }
});
CommandsRegistry.registerCommand({
    id: SET_EXPRESSION_COMMAND_ID,
    handler: async (accessor, expression) => {
        const debugService = accessor.get(IDebugService);
        if (expression instanceof Expression || expression instanceof Variable) {
            debugService.getViewModel().setSelectedExpression(expression, true);
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.setVariable',
    weight: KeybindingWeight.WorkbenchContrib + 5,
    when: CONTEXT_VARIABLES_FOCUSED,
    primary: KeyCode.F2,
    mac: { primary: KeyCode.Enter },
    handler: (accessor) => {
        const listService = accessor.get(IListService);
        const debugService = accessor.get(IDebugService);
        const focused = listService.lastFocusedList;
        if (focused) {
            const elements = focused.getFocus();
            if (Array.isArray(elements) && elements[0] instanceof Variable) {
                debugService.getViewModel().setSelectedExpression(elements[0], false);
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: REMOVE_EXPRESSION_COMMAND_ID,
    weight: KeybindingWeight.WorkbenchContrib,
    when: ( (ContextKeyExpr.and(
        CONTEXT_WATCH_EXPRESSIONS_FOCUSED,
         (CONTEXT_EXPRESSION_SELECTED.toNegated())
    ))),
    primary: KeyCode.Delete,
    mac: { primary: KeyMod$1.CtrlCmd | KeyCode.Backspace },
    handler: (accessor, expression) => {
        const debugService = accessor.get(IDebugService);
        if (expression instanceof Expression) {
            debugService.removeWatchExpressions(expression.getId());
            return;
        }
        const listService = accessor.get(IListService);
        const focused = listService.lastFocusedList;
        if (focused) {
            let elements = focused.getFocus();
            if (Array.isArray(elements) && elements[0] instanceof Expression) {
                const selection = focused.getSelection();
                if (selection && selection.indexOf(elements[0]) >= 0) {
                    elements = selection;
                }
                elements.forEach((e) => debugService.removeWatchExpressions(e.getId()));
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.removeBreakpoint',
    weight: KeybindingWeight.WorkbenchContrib,
    when: ( (ContextKeyExpr.and(
        CONTEXT_BREAKPOINTS_FOCUSED,
         (CONTEXT_BREAKPOINT_INPUT_FOCUSED.toNegated())
    ))),
    primary: KeyCode.Delete,
    mac: { primary: KeyMod$1.CtrlCmd | KeyCode.Backspace },
    handler: (accessor) => {
        const listService = accessor.get(IListService);
        const debugService = accessor.get(IDebugService);
        const list = listService.lastFocusedList;
        if (list instanceof List) {
            const focused = list.getFocusedElements();
            const element = focused.length ? focused[0] : undefined;
            if (element instanceof Breakpoint) {
                debugService.removeBreakpoints(element.getId());
            }
            else if (element instanceof FunctionBreakpoint) {
                debugService.removeFunctionBreakpoints(element.getId());
            }
            else if (element instanceof DataBreakpoint) {
                debugService.removeDataBreakpoints(element.getId());
            }
        }
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.installAdditionalDebuggers',
    weight: KeybindingWeight.WorkbenchContrib,
    when: undefined,
    primary: undefined,
    handler: async (accessor, query) => {
        const paneCompositeService = accessor.get(IPaneCompositePartService);
        const viewlet = (await paneCompositeService.openPaneComposite(VIEWLET_ID, ViewContainerLocation.Sidebar, true))?.getViewPaneContainer();
        let searchFor = `@category:debuggers`;
        if (typeof query === 'string') {
            searchFor += ` ${query}`;
        }
        viewlet.search(searchFor);
        viewlet.focus();
    }
});
registerAction2(class AddConfigurationAction extends Action2 {
    constructor() {
        super({
            id: ADD_CONFIGURATION_ID,
            title: ( localize2WithPath(_moduleId, 32, "Add Configuration...")),
            category: DEBUG_COMMAND_CATEGORY,
            f1: true,
            menu: {
                id: MenuId.EditorContent,
                when: ( (ContextKeyExpr.and(
                     (ContextKeyExpr.regex(ResourceContextKey.Path.key, /\.vscode[/\\]launch\.json$/)),
                     (ActiveEditorContext.isEqualTo(TEXT_FILE_EDITOR_ID))
                )))
            }
        });
    }
    async run(accessor, launchUri) {
        const manager = accessor.get(IDebugService).getConfigurationManager();
        const launch = manager.getLaunches().find(l => ( (l.uri.toString())) === launchUri) || manager.selectedConfiguration.launch;
        if (launch) {
            const { editor, created } = await launch.openConfigFile({ preserveFocus: false });
            if (editor && !created) {
                const codeEditor = editor.getControl();
                if (codeEditor) {
                    await codeEditor.getContribution(EDITOR_CONTRIBUTION_ID)?.addLaunchConfiguration();
                }
            }
        }
    }
});
const inlineBreakpointHandler = (accessor) => {
    const debugService = accessor.get(IDebugService);
    const editorService = accessor.get(IEditorService);
    const control = editorService.activeTextEditorControl;
    if (isCodeEditor(control)) {
        const position = control.getPosition();
        if (position && control.hasModel() && debugService.canSetBreakpointsIn(control.getModel())) {
            const modelUri = control.getModel().uri;
            const breakpointAlreadySet = ( (debugService.getModel().getBreakpoints({ lineNumber: position.lineNumber, uri: modelUri })
                .some(
                bp => (bp.sessionAgnosticData.column === position.column || (!bp.column && position.column <= 1))
            )));
            if (!breakpointAlreadySet) {
                debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber, column: position.column > 1 ? position.column : undefined }]);
            }
        }
    }
};
KeybindingsRegistry.registerCommandAndKeybindingRule({
    weight: KeybindingWeight.WorkbenchContrib,
    primary: KeyMod$1.Shift | KeyCode.F9,
    when: EditorContextKeys.editorTextFocus,
    id: TOGGLE_INLINE_BREAKPOINT_ID,
    handler: inlineBreakpointHandler
});
MenuRegistry.appendMenuItem(MenuId.EditorContext, {
    command: {
        id: TOGGLE_INLINE_BREAKPOINT_ID,
        title: ( localizeWithPath(_moduleId, 33, "Add Inline Breakpoint")),
        category: DEBUG_COMMAND_CATEGORY
    },
    when: ( (ContextKeyExpr.and(
        CONTEXT_IN_DEBUG_MODE,
         (PanelFocusContext.toNegated()),
        EditorContextKeys.editorTextFocus
    ))),
    group: 'debug',
    order: 1
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.openBreakpointToSide',
    weight: KeybindingWeight.WorkbenchContrib,
    when: CONTEXT_BREAKPOINTS_FOCUSED,
    primary: KeyMod$1.CtrlCmd | KeyCode.Enter,
    secondary: [KeyMod$1.Alt | KeyCode.Enter],
    handler: (accessor) => {
        const listService = accessor.get(IListService);
        const list = listService.lastFocusedList;
        if (list instanceof List) {
            const focus = list.getFocusedElements();
            if (focus.length && focus[0] instanceof Breakpoint) {
                return openBreakpointSource(focus[0], true, false, true, accessor.get(IDebugService), accessor.get(IEditorService));
            }
        }
        return undefined;
    }
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
    id: 'debug.openView',
    weight: KeybindingWeight.WorkbenchContrib,
    when: ( (CONTEXT_DEBUGGERS_AVAILABLE.toNegated())),
    primary: KeyCode.F5,
    secondary: [KeyMod$1.CtrlCmd | KeyCode.F5],
    handler: async (accessor) => {
        const paneCompositeService = accessor.get(IPaneCompositePartService);
        await paneCompositeService.openPaneComposite(VIEWLET_ID$1, ViewContainerLocation.Sidebar, true);
    }
});
export { ADD_CONFIGURATION_ID, ADD_TO_WATCH_ID, ADD_TO_WATCH_LABEL, CALLSTACK_BOTTOM_ID, CALLSTACK_BOTTOM_LABEL, CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CALLSTACK_UP_ID, CALLSTACK_UP_LABEL, CONTINUE_ID, CONTINUE_LABEL, COPY_EVALUATE_PATH_ID, COPY_EVALUATE_PATH_LABEL, COPY_STACK_TRACE_ID, COPY_VALUE_ID, COPY_VALUE_LABEL, DEBUG_COMMAND_CATEGORY, DEBUG_CONFIGURE_COMMAND_ID, DEBUG_CONFIGURE_LABEL, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_START_COMMAND_ID, DEBUG_START_LABEL, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, DISCONNECT_ID, DISCONNECT_LABEL, EDIT_EXPRESSION_COMMAND_ID, FOCUS_REPL_ID, FOCUS_SESSION_ID, FOCUS_SESSION_LABEL, JUMP_TO_CURSOR_ID, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, PAUSE_ID, PAUSE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, REMOVE_EXPRESSION_COMMAND_ID, RESTART_FRAME_ID, RESTART_LABEL, RESTART_SESSION_ID, REVERSE_CONTINUE_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, SELECT_DEBUG_SESSION_ID, SELECT_DEBUG_SESSION_LABEL, SET_EXPRESSION_COMMAND_ID, SHOW_LOADED_SCRIPTS_ID, STEP_BACK_ID, STEP_INTO_ID, STEP_INTO_LABEL, STEP_INTO_TARGET_ID, STEP_INTO_TARGET_LABEL, STEP_OUT_ID, STEP_OUT_LABEL, STEP_OVER_ID, STEP_OVER_LABEL, STOP_ID, STOP_LABEL, TERMINATE_THREAD_ID, TOGGLE_INLINE_BREAKPOINT_ID };
