import { getDomNodePagePosition } from "../../../../base/browser/dom.mjs";
import { Action, Separator } from "../../../../base/common/actions.mjs";
import { CancellationToken } from "../../../../base/common/cancellation.mjs";
import { EditorExtensionsRegistry } from "../../../browser/editorExtensions.mjs";
import { Range } from "../../../common/core/range.mjs";
import { ITextModelService } from "../../../common/services/resolverService.mjs";
import { SymbolNavigationAction, SymbolNavigationAnchor, DefinitionAction } from "../../gotoSymbol/browser/goToCommands.mjs";
import { PeekContext } from "../../peekView/browser/peekView.mjs";
import { MenuRegistry, MenuId, isIMenuItem } from "../../../../platform/actions/common/actions.mjs";
import { ICommandService } from "../../../../platform/commands/common/commands.mjs";
import { IContextKeyService } from "../../../../platform/contextkey/common/contextkey.mjs";
import { IContextMenuService } from "../../../../platform/contextview/browser/contextView.mjs";
import { IInstantiationService } from "../../../../platform/instantiation/common/instantiation.mjs";
import { INotificationService, Severity } from "../../../../platform/notification/common/notification.mjs";
var __awaiter = globalThis && globalThis.__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());
  });
};
function showGoToContextMenu(accessor, editor, anchor, part) {
  var _a;
  return __awaiter(this, void 0, void 0, function* () {
    const resolverService = accessor.get(ITextModelService);
    const contextMenuService = accessor.get(IContextMenuService);
    const commandService = accessor.get(ICommandService);
    const instaService = accessor.get(IInstantiationService);
    const notificationService = accessor.get(INotificationService);
    yield part.item.resolve(CancellationToken.None);
    if (!part.part.location) {
      return;
    }
    const location = part.part.location;
    const menuActions = [];
    const filter = new Set(MenuRegistry.getMenuItems(MenuId.EditorContext).map((item) => isIMenuItem(item) ? item.command.id : ""));
    for (const delegate of EditorExtensionsRegistry.getEditorActions()) {
      if (delegate instanceof SymbolNavigationAction && filter.has(delegate.id)) {
        menuActions.push(new Action(delegate.id, delegate.label, void 0, true, () => __awaiter(this, void 0, void 0, function* () {
          const ref = yield resolverService.createModelReference(location.uri);
          try {
            yield instaService.invokeFunction(delegate.run.bind(delegate), editor, new SymbolNavigationAnchor(ref.object.textEditorModel, Range.getStartPosition(location.range)));
          } finally {
            ref.dispose();
          }
        })));
      }
    }
    if (part.part.command) {
      const { command } = part.part;
      menuActions.push(new Separator());
      menuActions.push(new Action(command.id, command.title, void 0, true, () => __awaiter(this, void 0, void 0, function* () {
        var _b;
        try {
          yield commandService.executeCommand(command.id, ...(_b = command.arguments) !== null && _b !== void 0 ? _b : []);
        } catch (err) {
          notificationService.notify({
            severity: Severity.Error,
            source: part.item.provider.displayName,
            message: err
          });
        }
      })));
    }
    const useShadowDOM = editor.getOption(
      115
      /* useShadowDOM */
    );
    contextMenuService.showContextMenu({
      domForShadowRoot: useShadowDOM ? (_a = editor.getDomNode()) !== null && _a !== void 0 ? _a : void 0 : void 0,
      getAnchor: () => {
        const box = getDomNodePagePosition(anchor);
        return { x: box.left, y: box.top + box.height + 8 };
      },
      getActions: () => menuActions,
      onHide: () => {
        editor.focus();
      },
      autoSelectFirstItem: true
    });
  });
}
function goToDefinitionWithLocation(accessor, event, editor, location) {
  return __awaiter(this, void 0, void 0, function* () {
    const resolverService = accessor.get(ITextModelService);
    const ref = yield resolverService.createModelReference(location.uri);
    yield editor.invokeWithinContext((accessor2) => __awaiter(this, void 0, void 0, function* () {
      const openToSide = event.hasSideBySideModifier;
      const contextKeyService = accessor2.get(IContextKeyService);
      const isInPeek = PeekContext.inPeekEditor.getValue(contextKeyService);
      const canPeek = !openToSide && editor.getOption(
        78
        /* definitionLinkOpensInPeek */
      ) && !isInPeek;
      const action = new DefinitionAction({ openToSide, openInPeek: canPeek, muteMessage: true }, { alias: "", label: "", id: "", precondition: void 0 });
      return action.run(accessor2, editor, { model: ref.object.textEditorModel, position: Range.getStartPosition(location.range) });
    }));
    ref.dispose();
  });
}
export {
  goToDefinitionWithLocation,
  showGoToContextMenu
};
