"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const async = require("../../../../base/common/async.js");
const htmlContent = require("../../../../base/common/htmlContent.js");
const position = require("../../../common/core/position.js");
const textModel = require("../../../common/model/textModel.js");
const hoverTypes = require("../../hover/browser/hoverTypes.js");
const language = require("../../../common/languages/language.js");
const resolverService = require("../../../common/services/resolverService.js");
const getHover = require("../../hover/browser/getHover.js");
const markdownHoverParticipant = require("../../hover/browser/markdownHoverParticipant.js");
const inlayHintsController = require("./inlayHintsController.js");
const configuration = require("../../../../platform/configuration/common/configuration.js");
const opener = require("../../../../platform/opener/common/opener.js");
const languageFeatures = require("../../../common/services/languageFeatures.js");
const nls = require("../../../../nls.js");
const platform = require("../../../../base/common/platform.js");
const inlayHints = require("./inlayHints.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());
  });
};
var __asyncValues = globalThis && globalThis.__asyncValues || function(o) {
  if (!Symbol.asyncIterator)
    throw new TypeError("Symbol.asyncIterator is not defined.");
  var m = o[Symbol.asyncIterator], i;
  return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
    return this;
  }, i);
  function verb(n) {
    i[n] = o[n] && function(v) {
      return new Promise(function(resolve, reject) {
        v = o[n](v), settle(resolve, reject, v.done, v.value);
      });
    };
  }
  function settle(resolve, reject, d, v) {
    Promise.resolve(v).then(function(v2) {
      resolve({ value: v2, done: d });
    }, reject);
  }
};
class InlayHintsHoverAnchor extends hoverTypes.HoverForeignElementAnchor {
  constructor(part, owner) {
    super(10, owner, part.item.anchor.range);
    this.part = part;
  }
}
exports.InlayHintsHover = class InlayHintsHover extends markdownHoverParticipant.MarkdownHoverParticipant {
  constructor(editor, languageService, openerService, configurationService, _resolverService, languageFeaturesService) {
    super(editor, languageService, openerService, configurationService, languageFeaturesService);
    this._resolverService = _resolverService;
    this.hoverOrdinal = 6;
  }
  suggestHoverAnchor(mouseEvent) {
    var _a;
    const controller = inlayHintsController.InlayHintsController.get(this._editor);
    if (!controller) {
      return null;
    }
    if (mouseEvent.target.type !== 6) {
      return null;
    }
    const options = (_a = mouseEvent.target.detail.injectedText) === null || _a === void 0 ? void 0 : _a.options;
    if (!(options instanceof textModel.ModelDecorationInjectedTextOptions && options.attachedData instanceof inlayHintsController.RenderedInlayHintLabelPart)) {
      return null;
    }
    return new InlayHintsHoverAnchor(options.attachedData, this);
  }
  computeSync() {
    return [];
  }
  computeAsync(anchor, _lineDecorations, token) {
    if (!(anchor instanceof InlayHintsHoverAnchor)) {
      return async.AsyncIterableObject.EMPTY;
    }
    return new async.AsyncIterableObject((executor) => __awaiter(this, void 0, void 0, function* () {
      var e_1, _a;
      const { part } = anchor;
      yield part.item.resolve(token);
      if (token.isCancellationRequested) {
        return;
      }
      let itemTooltip;
      if (typeof part.item.hint.tooltip === "string") {
        itemTooltip = new htmlContent.MarkdownString().appendText(part.item.hint.tooltip);
      } else if (part.item.hint.tooltip) {
        itemTooltip = part.item.hint.tooltip;
      }
      if (itemTooltip) {
        executor.emitOne(new markdownHoverParticipant.MarkdownHover(this, anchor.range, [itemTooltip], 0));
      }
      let partTooltip;
      if (typeof part.part.tooltip === "string") {
        partTooltip = new htmlContent.MarkdownString().appendText(part.part.tooltip);
      } else if (part.part.tooltip) {
        partTooltip = part.part.tooltip;
      }
      if (partTooltip) {
        executor.emitOne(new markdownHoverParticipant.MarkdownHover(this, anchor.range, [partTooltip], 1));
      }
      if (part.part.location || part.part.command) {
        let linkHint;
        const useMetaKey = this._editor.getOption(
          70
          /* multiCursorModifier */
        ) === "altKey";
        const kb = useMetaKey ? platform.isMacintosh ? nls.localize("links.navigate.kb.meta.mac", "cmd + click") : nls.localize("links.navigate.kb.meta", "ctrl + click") : platform.isMacintosh ? nls.localize("links.navigate.kb.alt.mac", "option + click") : nls.localize("links.navigate.kb.alt", "alt + click");
        if (part.part.location && part.part.command) {
          linkHint = new htmlContent.MarkdownString().appendText(nls.localize("hint.defAndCommand", "Go to Definition ({0}), right click for more", kb));
        } else if (part.part.location) {
          linkHint = new htmlContent.MarkdownString().appendText(nls.localize("hint.def", "Go to Definition ({0})", kb));
        } else if (part.part.command) {
          linkHint = new htmlContent.MarkdownString(`[${nls.localize("hint.cmd", "Execute Command")}](${inlayHints.asCommandLink(part.part.command)} "${part.part.command.title}") (${kb})`, { isTrusted: true });
        }
        if (linkHint) {
          executor.emitOne(new markdownHoverParticipant.MarkdownHover(this, anchor.range, [linkHint], 1e4));
        }
      }
      const iterable = yield this._resolveInlayHintLabelPartHover(part, token);
      try {
        for (var iterable_1 = __asyncValues(iterable), iterable_1_1; iterable_1_1 = yield iterable_1.next(), !iterable_1_1.done; ) {
          let item = iterable_1_1.value;
          executor.emitOne(item);
        }
      } catch (e_1_1) {
        e_1 = { error: e_1_1 };
      } finally {
        try {
          if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return))
            yield _a.call(iterable_1);
        } finally {
          if (e_1)
            throw e_1.error;
        }
      }
    }));
  }
  _resolveInlayHintLabelPartHover(part, token) {
    return __awaiter(this, void 0, void 0, function* () {
      if (!part.part.location) {
        return async.AsyncIterableObject.EMPTY;
      }
      const { uri, range } = part.part.location;
      const ref = yield this._resolverService.createModelReference(uri);
      try {
        const model = ref.object.textEditorModel;
        if (!this._languageFeaturesService.hoverProvider.has(model)) {
          return async.AsyncIterableObject.EMPTY;
        }
        return getHover.getHover(this._languageFeaturesService.hoverProvider, model, new position.Position(range.startLineNumber, range.startColumn), token).filter((item) => !htmlContent.isEmptyMarkdownString(item.hover.contents)).map((item) => new markdownHoverParticipant.MarkdownHover(this, part.item.anchor.range, item.hover.contents, 2 + item.ordinal));
      } finally {
        ref.dispose();
      }
    });
  }
};
exports.InlayHintsHover = __decorate([
  __param(1, language.ILanguageService),
  __param(2, opener.IOpenerService),
  __param(3, configuration.IConfigurationService),
  __param(4, resolverService.ITextModelService),
  __param(5, languageFeatures.ILanguageFeaturesService)
], exports.InlayHintsHover);
