/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { Codicon } from '../../../../base/common/codicons.js';
import { KeyChord } from '../../../../base/common/keyCodes.js';
import { EditorAction2 } from '../../../browser/editorExtensions.js';
import { EmbeddedCodeEditorWidget } from '../../../browser/widget/embeddedCodeEditorWidget.js';
import { EditorContextKeys } from '../../../common/editorContextKeys.js';
import { InteractiveEditorController } from './interactiveEditorWidget.js';
import { CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST, CTX_INTERACTIVE_EDITOR_HAS_PROVIDER, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST, CTX_INTERACTIVE_EDITOR_EMPTY, CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION, CTX_INTERACTIVE_EDITOR_PREVIEW, CTX_INTERACTIVE_EDITOR_VISIBLE, MENU_INTERACTIVE_EDITOR_WIDGET, MENU_INTERACTIVE_EDITOR_WIDGET_LHS, CTX_INTERACTIVE_EDITOR_HISTORY_VISIBLE } from '../common/interactiveEditor.js';
import { localize } from '../../../../nls.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';
export class StartSessionAction extends EditorAction2 {
    constructor() {
        super({
            id: 'interactiveEditor.start',
            title: { value: localize('run', 'Start Session'), original: 'Start Session' },
            category: AbstractInteractiveEditorAction.category,
            f1: true,
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_HAS_PROVIDER, EditorContextKeys.writable),
            keybinding: {
                weight: 200 /* KeybindingWeight.WorkbenchContrib */,
                primary: KeyChord(2048 /* KeyMod.CtrlCmd */ | 41 /* KeyCode.KeyK */, 39 /* KeyCode.KeyI */)
            }
        });
    }
    runEditorCommand(_accessor, editor, ..._args) {
        var _a;
        (_a = InteractiveEditorController.get(editor)) === null || _a === void 0 ? void 0 : _a.run();
    }
}
class AbstractInteractiveEditorAction extends EditorAction2 {
    constructor(desc) {
        super(Object.assign(Object.assign({}, desc), { category: AbstractInteractiveEditorAction.category, precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_HAS_PROVIDER, desc.precondition) }));
    }
    runEditorCommand(accessor, editor, ..._args) {
        if (editor instanceof EmbeddedCodeEditorWidget) {
            editor = editor.getParentEditor();
        }
        const ctrl = InteractiveEditorController.get(editor);
        if (!ctrl) {
            return;
        }
        this.runInteractiveEditorCommand(accessor, ctrl, editor, ..._args);
    }
}
AbstractInteractiveEditorAction.category = { value: localize('cat', 'Interactive Editor'), original: 'Interactive Editor' };
export class MakeRequestAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.accept',
            title: localize('accept', 'Make Request'),
            icon: Codicon.arrowUp,
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_EMPTY.negate()),
            keybinding: {
                when: CTX_INTERACTIVE_EDITOR_FOCUSED,
                weight: 0 /* KeybindingWeight.EditorCore */ + 7,
                primary: 3 /* KeyCode.Enter */
            },
            menu: {
                id: MENU_INTERACTIVE_EDITOR_WIDGET,
                group: 'main',
                order: 1,
                when: CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST.isEqualTo(false)
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.accept();
    }
}
export class StopRequestAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.stop',
            title: localize('stop', 'Stop Request'),
            icon: Codicon.debugStop,
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_EMPTY.negate(), CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST),
            menu: {
                id: MENU_INTERACTIVE_EDITOR_WIDGET,
                group: 'main',
                order: 1,
                when: CTX_INTERACTIVE_EDITOR_HAS_ACTIVE_REQUEST
            },
            keybinding: {
                weight: 100 /* KeybindingWeight.EditorContrib */,
                primary: 9 /* KeyCode.Escape */
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.cancelCurrentRequest();
    }
}
export class AcceptWithPreviewInteractiveEditorAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.acceptWithPreview',
            title: localize('acceptPreview', 'Ask Question & Preview Reply'),
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_EMPTY.negate()),
            keybinding: {
                when: CTX_INTERACTIVE_EDITOR_FOCUSED,
                weight: 0 /* KeybindingWeight.EditorCore */ + 7,
                primary: 1024 /* KeyMod.Shift */ + 3 /* KeyCode.Enter */
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.accept(true);
    }
}
export class TogglePreviewMode extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.togglePreview',
            title: localize('togglePreview', 'Inline Preview'),
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE),
            toggled: CTX_INTERACTIVE_EDITOR_PREVIEW,
            menu: {
                id: MENU_INTERACTIVE_EDITOR_WIDGET,
                group: 'C',
                order: 1
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.togglePreview();
    }
}
export class CancelSessionAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.cancel',
            title: localize('cancel', 'Cancel'),
            precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
            keybinding: {
                weight: 100 /* KeybindingWeight.EditorContrib */ - 1,
                primary: 9 /* KeyCode.Escape */
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.cancelSession();
    }
}
export class ArrowOutUpAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.arrowOutUp',
            title: localize('arrowUp', 'Cursor Up'),
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST),
            keybinding: {
                weight: 0 /* KeybindingWeight.EditorCore */,
                primary: 16 /* KeyCode.UpArrow */
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.arrowOut(true);
    }
}
export class ArrowOutDownAction extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.arrowOutDown',
            title: localize('arrowDown', 'Cursor Down'),
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST),
            keybinding: {
                weight: 0 /* KeybindingWeight.EditorCore */,
                primary: 18 /* KeyCode.DownArrow */
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.arrowOut(false);
    }
}
export class FocusInteractiveEditor extends EditorAction2 {
    constructor() {
        super({
            id: 'interactiveEditor.focus',
            title: localize('focus', 'Focus'),
            category: AbstractInteractiveEditorAction.category,
            precondition: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_FOCUSED.negate()),
            keybinding: [{
                    weight: 0 /* KeybindingWeight.EditorCore */ + 10,
                    when: CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('above'),
                    primary: 18 /* KeyCode.DownArrow */,
                }, {
                    weight: 0 /* KeybindingWeight.EditorCore */ + 10,
                    when: CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('below'),
                    primary: 16 /* KeyCode.UpArrow */,
                }]
        });
    }
    runEditorCommand(_accessor, editor, ..._args) {
        var _a;
        (_a = InteractiveEditorController.get(editor)) === null || _a === void 0 ? void 0 : _a.focus();
    }
}
export class PreviousFromHistory extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.previousFromHistory',
            title: localize('previousFromHistory', 'Previous From History'),
            precondition: CTX_INTERACTIVE_EDITOR_FOCUSED,
            keybinding: {
                weight: 0 /* KeybindingWeight.EditorCore */ + 10,
                primary: 2048 /* KeyMod.CtrlCmd */ | 16 /* KeyCode.UpArrow */,
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.populateHistory(true);
    }
}
export class NextFromHistory extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.nextFromHistory',
            title: localize('nextFromHistory', 'Next From History'),
            precondition: CTX_INTERACTIVE_EDITOR_FOCUSED,
            keybinding: {
                weight: 0 /* KeybindingWeight.EditorCore */ + 10,
                primary: 2048 /* KeyMod.CtrlCmd */ | 18 /* KeyCode.DownArrow */,
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.populateHistory(false);
    }
}
export class UndoCommand extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.undo',
            title: localize('undo', 'Undo'),
            icon: Codicon.commentDiscussion,
            precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_VISIBLE),
            keybinding: {
                weight: 100 /* KeybindingWeight.EditorContrib */ + 10,
                primary: 2048 /* KeyMod.CtrlCmd */ | 56 /* KeyCode.KeyZ */,
            },
            menu: {
                id: MENU_INTERACTIVE_EDITOR_WIDGET,
                group: 'B',
                order: 1
            }
        });
    }
    runInteractiveEditorCommand(_accessor, _ctrl, editor, ..._args) {
        var _a;
        (_a = editor.getModel()) === null || _a === void 0 ? void 0 : _a.undo();
    }
}
export class ToggleHistory extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.toggleHistory',
            title: localize('toggleHistory', 'Toggle History'),
            icon: Codicon.chevronRight,
            precondition: CTX_INTERACTIVE_EDITOR_VISIBLE,
            toggled: {
                condition: CTX_INTERACTIVE_EDITOR_HISTORY_VISIBLE,
                icon: Codicon.chevronDown,
            },
            menu: {
                id: MENU_INTERACTIVE_EDITOR_WIDGET_LHS,
                group: 'main',
                order: 1
            }
        });
    }
    runInteractiveEditorCommand(_accessor, ctrl, _editor, ..._args) {
        ctrl.toggleHistory();
    }
}
export class CopyRecordings extends AbstractInteractiveEditorAction {
    constructor() {
        super({
            id: 'interactiveEditor.copyRecordings',
            f1: true,
            title: {
                value: localize('copyRecordings', '(Developer) Write Exchange to Clipboard'), original: '(Developer) Write Exchange to Clipboard'
            }
        });
    }
    runInteractiveEditorCommand(accessor, ctrl, _editor, ..._args) {
        return __awaiter(this, void 0, void 0, function* () {
            const clipboardService = accessor.get(IClipboardService);
            const quickPickService = accessor.get(IQuickInputService);
            const picks = ctrl.recordings().map(rec => {
                return {
                    rec,
                    label: localize('label', "{0} messages, started {1}", rec.exchanges.length, rec.when.toLocaleTimeString()),
                    tooltip: rec.exchanges.map(ex => ex.req.prompt).join('\n'),
                };
            });
            if (picks.length === 0) {
                return;
            }
            let pick;
            if (picks.length === 1) {
                pick = picks[0];
            }
            else {
                pick = yield quickPickService.pick(picks, { canPickMany: false });
            }
            if (pick) {
                clipboardService.writeText(JSON.stringify(pick.rec, undefined, 2));
            }
        });
    }
}
