"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const cancellation = require("../../../../base/common/cancellation.js");
const lazy = require("../../../../base/common/lazy.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const strings = require("../../../../base/common/strings.js");
const editorExtensions = require("../../../browser/editorExtensions.js");
const bulkEditService = require("../../../browser/services/bulkEditService.js");
const editorContextKeys = require("../../../common/editorContextKeys.js");
const languageFeatures = require("../../../common/services/languageFeatures.js");
const codeAction = require("./codeAction.js");
const codeActionUi = require("./codeActionUi.js");
const messageController = require("../../message/browser/messageController.js");
const nls = require("../../../../nls.js");
const commands = require("../../../../platform/commands/common/commands.js");
const contextkey = require("../../../../platform/contextkey/common/contextkey.js");
const instantiation = require("../../../../platform/instantiation/common/instantiation.js");
const markers = require("../../../../platform/markers/common/markers.js");
const notification = require("../../../../platform/notification/common/notification.js");
const progress = require("../../../../platform/progress/common/progress.js");
const telemetry = require("../../../../platform/telemetry/common/telemetry.js");
const codeActionModel = require("./codeActionModel.js");
const types = require("./types.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
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 contextKeyForSupportedActions(kind) {
  return contextkey.ContextKeyExpr.regex(codeActionModel.SUPPORTED_CODE_ACTIONS.keys()[0], new RegExp("(\\s|^)" + strings.escapeRegExpCharacters(kind.value) + "\\b"));
}
const argsSchema = {
  type: "object",
  defaultSnippets: [{ body: { kind: "" } }],
  properties: {
    "kind": {
      type: "string",
      description: nls.localize("args.schema.kind", "Kind of the code action to run.")
    },
    "apply": {
      type: "string",
      description: nls.localize("args.schema.apply", "Controls when the returned actions are applied."),
      default: "ifSingle",
      enum: [
        "first",
        "ifSingle",
        "never"
        /* Never */
      ],
      enumDescriptions: [
        nls.localize("args.schema.apply.first", "Always apply the first returned code action."),
        nls.localize("args.schema.apply.ifSingle", "Apply the first returned code action if it is the only one."),
        nls.localize("args.schema.apply.never", "Do not apply the returned code actions.")
      ]
    },
    "preferred": {
      type: "boolean",
      default: false,
      description: nls.localize("args.schema.preferred", "Controls if only preferred code actions should be returned.")
    }
  }
};
exports.QuickFixController = class QuickFixController extends lifecycle.Disposable {
  constructor(editor, markerService, contextKeyService, progressService, _instantiationService, languageFeaturesService) {
    super();
    this._instantiationService = _instantiationService;
    this._editor = editor;
    this._model = this._register(new codeActionModel.CodeActionModel(this._editor, languageFeaturesService.codeActionProvider, markerService, contextKeyService, progressService));
    this._register(this._model.onDidChangeState((newState) => this.update(newState)));
    this._ui = new lazy.Lazy(() => this._register(new codeActionUi.CodeActionUi(editor, QuickFixAction.Id, AutoFixAction.Id, {
      applyCodeAction: (action, retrigger) => __awaiter(this, void 0, void 0, function* () {
        try {
          yield this._applyCodeAction(action);
        } finally {
          if (retrigger) {
            this._trigger({ type: 2, filter: {} });
          }
        }
      })
    }, this._instantiationService)));
  }
  static get(editor) {
    return editor.getContribution(QuickFixController.ID);
  }
  update(newState) {
    this._ui.getValue().update(newState);
  }
  showCodeActions(trigger, actions, at) {
    return this._ui.getValue().showCodeActionList(trigger, actions, at, { includeDisabledActions: false });
  }
  manualTriggerAtCurrentPosition(notAvailableMessage, filter, autoApply) {
    var _a;
    if (!this._editor.hasModel()) {
      return;
    }
    (_a = messageController.MessageController.get(this._editor)) === null || _a === void 0 ? void 0 : _a.closeMessage();
    const triggerPosition = this._editor.getPosition();
    this._trigger({ type: 1, filter, autoApply, context: { notAvailableMessage, position: triggerPosition } });
  }
  _trigger(trigger) {
    return this._model.trigger(trigger);
  }
  _applyCodeAction(action) {
    return this._instantiationService.invokeFunction(applyCodeAction, action, this._editor);
  }
};
exports.QuickFixController.ID = "editor.contrib.quickFixController";
exports.QuickFixController = __decorate([
  __param(1, markers.IMarkerService),
  __param(2, contextkey.IContextKeyService),
  __param(3, progress.IEditorProgressService),
  __param(4, instantiation.IInstantiationService),
  __param(5, languageFeatures.ILanguageFeaturesService)
], exports.QuickFixController);
function applyCodeAction(accessor, item, editor) {
  return __awaiter(this, void 0, void 0, function* () {
    const bulkEditService$1 = accessor.get(bulkEditService.IBulkEditService);
    const commandService = accessor.get(commands.ICommandService);
    const telemetryService = accessor.get(telemetry.ITelemetryService);
    const notificationService = accessor.get(notification.INotificationService);
    telemetryService.publicLog2("codeAction.applyCodeAction", {
      codeActionTitle: item.action.title,
      codeActionKind: item.action.kind,
      codeActionIsPreferred: !!item.action.isPreferred
    });
    yield item.resolve(cancellation.CancellationToken.None);
    if (item.action.edit) {
      yield bulkEditService$1.apply(bulkEditService.ResourceEdit.convert(item.action.edit), { editor, label: item.action.title });
    }
    if (item.action.command) {
      try {
        yield commandService.executeCommand(item.action.command.id, ...item.action.command.arguments || []);
      } catch (err) {
        const message = asMessage(err);
        notificationService.error(typeof message === "string" ? message : nls.localize("applyCodeActionFailed", "An unknown error occurred while applying the code action"));
      }
    }
  });
}
function asMessage(err) {
  if (typeof err === "string") {
    return err;
  } else if (err instanceof Error && typeof err.message === "string") {
    return err.message;
  } else {
    return void 0;
  }
}
function triggerCodeActionsForEditorSelection(editor, notAvailableMessage, filter, autoApply) {
  if (editor.hasModel()) {
    const controller = exports.QuickFixController.get(editor);
    if (controller) {
      controller.manualTriggerAtCurrentPosition(notAvailableMessage, filter, autoApply);
    }
  }
}
class QuickFixAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: QuickFixAction.Id,
      label: nls.localize("quickfix.trigger.label", "Quick Fix..."),
      alias: "Quick Fix...",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, editorContextKeys.EditorContextKeys.hasCodeActionsProvider),
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 84,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    return triggerCodeActionsForEditorSelection(editor, nls.localize("editor.action.quickFix.noneMessage", "No code actions available"), void 0, void 0);
  }
}
QuickFixAction.Id = "editor.action.quickFix";
class CodeActionCommand extends editorExtensions.EditorCommand {
  constructor() {
    super({
      id: codeAction.codeActionCommandId,
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, editorContextKeys.EditorContextKeys.hasCodeActionsProvider),
      description: {
        description: "Trigger a code action",
        args: [{ name: "args", schema: argsSchema }]
      }
    });
  }
  runEditorCommand(_accessor, editor, userArgs) {
    const args = types.CodeActionCommandArgs.fromUser(userArgs, {
      kind: types.CodeActionKind.Empty,
      apply: "ifSingle"
    });
    return triggerCodeActionsForEditorSelection(editor, typeof (userArgs === null || userArgs === void 0 ? void 0 : userArgs.kind) === "string" ? args.preferred ? nls.localize("editor.action.codeAction.noneMessage.preferred.kind", "No preferred code actions for '{0}' available", userArgs.kind) : nls.localize("editor.action.codeAction.noneMessage.kind", "No code actions for '{0}' available", userArgs.kind) : args.preferred ? nls.localize("editor.action.codeAction.noneMessage.preferred", "No preferred code actions available") : nls.localize("editor.action.codeAction.noneMessage", "No code actions available"), {
      include: args.kind,
      includeSourceActions: true,
      onlyIncludePreferredActions: args.preferred
    }, args.apply);
  }
}
class RefactorAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: codeAction.refactorCommandId,
      label: nls.localize("refactor.label", "Refactor..."),
      alias: "Refactor...",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, editorContextKeys.EditorContextKeys.hasCodeActionsProvider),
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 2048 | 1024 | 48,
        mac: {
          primary: 256 | 1024 | 48
          /* KeyR */
        },
        weight: 100
        /* EditorContrib */
      },
      contextMenuOpts: {
        group: "1_modification",
        order: 2,
        when: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, contextKeyForSupportedActions(types.CodeActionKind.Refactor))
      },
      description: {
        description: "Refactor...",
        args: [{ name: "args", schema: argsSchema }]
      }
    });
  }
  run(_accessor, editor, userArgs) {
    const args = types.CodeActionCommandArgs.fromUser(userArgs, {
      kind: types.CodeActionKind.Refactor,
      apply: "never"
      /* Never */
    });
    return triggerCodeActionsForEditorSelection(editor, typeof (userArgs === null || userArgs === void 0 ? void 0 : userArgs.kind) === "string" ? args.preferred ? nls.localize("editor.action.refactor.noneMessage.preferred.kind", "No preferred refactorings for '{0}' available", userArgs.kind) : nls.localize("editor.action.refactor.noneMessage.kind", "No refactorings for '{0}' available", userArgs.kind) : args.preferred ? nls.localize("editor.action.refactor.noneMessage.preferred", "No preferred refactorings available") : nls.localize("editor.action.refactor.noneMessage", "No refactorings available"), {
      include: types.CodeActionKind.Refactor.contains(args.kind) ? args.kind : types.CodeActionKind.None,
      onlyIncludePreferredActions: args.preferred
    }, args.apply);
  }
}
class SourceAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: codeAction.sourceActionCommandId,
      label: nls.localize("source.label", "Source Action..."),
      alias: "Source Action...",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, editorContextKeys.EditorContextKeys.hasCodeActionsProvider),
      contextMenuOpts: {
        group: "1_modification",
        order: 2.1,
        when: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, contextKeyForSupportedActions(types.CodeActionKind.Source))
      },
      description: {
        description: "Source Action...",
        args: [{ name: "args", schema: argsSchema }]
      }
    });
  }
  run(_accessor, editor, userArgs) {
    const args = types.CodeActionCommandArgs.fromUser(userArgs, {
      kind: types.CodeActionKind.Source,
      apply: "never"
      /* Never */
    });
    return triggerCodeActionsForEditorSelection(editor, typeof (userArgs === null || userArgs === void 0 ? void 0 : userArgs.kind) === "string" ? args.preferred ? nls.localize("editor.action.source.noneMessage.preferred.kind", "No preferred source actions for '{0}' available", userArgs.kind) : nls.localize("editor.action.source.noneMessage.kind", "No source actions for '{0}' available", userArgs.kind) : args.preferred ? nls.localize("editor.action.source.noneMessage.preferred", "No preferred source actions available") : nls.localize("editor.action.source.noneMessage", "No source actions available"), {
      include: types.CodeActionKind.Source.contains(args.kind) ? args.kind : types.CodeActionKind.None,
      includeSourceActions: true,
      onlyIncludePreferredActions: args.preferred
    }, args.apply);
  }
}
class OrganizeImportsAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: codeAction.organizeImportsCommandId,
      label: nls.localize("organizeImports.label", "Organize Imports"),
      alias: "Organize Imports",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, contextKeyForSupportedActions(types.CodeActionKind.SourceOrganizeImports)),
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 1024 | 512 | 45,
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    return triggerCodeActionsForEditorSelection(
      editor,
      nls.localize("editor.action.organize.noneMessage", "No organize imports action available"),
      { include: types.CodeActionKind.SourceOrganizeImports, includeSourceActions: true },
      "ifSingle"
      /* IfSingle */
    );
  }
}
class FixAllAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: codeAction.fixAllCommandId,
      label: nls.localize("fixAll.label", "Fix All"),
      alias: "Fix All",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, contextKeyForSupportedActions(types.CodeActionKind.SourceFixAll))
    });
  }
  run(_accessor, editor) {
    return triggerCodeActionsForEditorSelection(
      editor,
      nls.localize("fixAll.noneMessage", "No fix all action available"),
      { include: types.CodeActionKind.SourceFixAll, includeSourceActions: true },
      "ifSingle"
      /* IfSingle */
    );
  }
}
class AutoFixAction extends editorExtensions.EditorAction {
  constructor() {
    super({
      id: AutoFixAction.Id,
      label: nls.localize("autoFix.label", "Auto Fix..."),
      alias: "Auto Fix...",
      precondition: contextkey.ContextKeyExpr.and(editorContextKeys.EditorContextKeys.writable, contextKeyForSupportedActions(types.CodeActionKind.QuickFix)),
      kbOpts: {
        kbExpr: editorContextKeys.EditorContextKeys.editorTextFocus,
        primary: 512 | 1024 | 84,
        mac: {
          primary: 2048 | 512 | 84
          /* Period */
        },
        weight: 100
        /* EditorContrib */
      }
    });
  }
  run(_accessor, editor) {
    return triggerCodeActionsForEditorSelection(
      editor,
      nls.localize("editor.action.autoFix.noneMessage", "No auto fixes available"),
      {
        include: types.CodeActionKind.QuickFix,
        onlyIncludePreferredActions: true
      },
      "ifSingle"
      /* IfSingle */
    );
  }
}
AutoFixAction.Id = "editor.action.autoFix";
exports.AutoFixAction = AutoFixAction;
exports.CodeActionCommand = CodeActionCommand;
exports.FixAllAction = FixAllAction;
exports.OrganizeImportsAction = OrganizeImportsAction;
exports.QuickFixAction = QuickFixAction;
exports.RefactorAction = RefactorAction;
exports.SourceAction = SourceAction;
exports.applyCodeAction = applyCodeAction;
