import { Position as u, Range as f } from "../../../../../vscode-languageserver-types@3.17.5/node_modules/vscode-languageserver-types/lib/esm/main.js";
import { NEWLINE_REGEXP as C, escapeRegExp as N } from "../utils/regexp-utils.js";
import "../utils/uri-utils.js";
import { URI as z } from "../../../../../vscode-uri@3.0.8/node_modules/vscode-uri/lib/esm/index.js";
function Z(n, e, t) {
  let i, s;
  typeof n == "string" ? (s = e, i = t) : (s = n.range.start, i = e), s || (s = u.create(0, 0));
  const r = L(n), l = S(i), a = O({
    lines: r,
    position: s,
    options: l
  });
  return G({
    index: 0,
    tokens: a,
    position: s
  });
}
function I(n, e) {
  const t = S(e), i = L(n);
  if (i.length === 0)
    return !1;
  const s = i[0], r = i[i.length - 1], l = t.start, a = t.end;
  return !!(l != null && l.exec(s)) && !!(a != null && a.exec(r));
}
function L(n) {
  let e = "";
  return typeof n == "string" ? e = n : e = n.text, e.split(C);
}
const $ = /\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy, A = /\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;
function O(n) {
  var e, t, i;
  const s = [];
  let r = n.position.line, l = n.position.character;
  for (let a = 0; a < n.lines.length; a++) {
    const h = a === 0, d = a === n.lines.length - 1;
    let o = n.lines[a], g = 0;
    if (h && n.options.start) {
      const c = (e = n.options.start) === null || e === void 0 ? void 0 : e.exec(o);
      c && (g = c.index + c[0].length);
    } else {
      const c = (t = n.options.line) === null || t === void 0 ? void 0 : t.exec(o);
      c && (g = c.index + c[0].length);
    }
    if (d) {
      const c = (i = n.options.end) === null || i === void 0 ? void 0 : i.exec(o);
      c && (o = o.substring(0, c.index));
    }
    if (o = o.substring(0, j(o)), w(o, g) >= o.length) {
      if (s.length > 0) {
        const c = u.create(r, l);
        s.push({
          type: "break",
          content: "",
          range: f.create(c, c)
        });
      }
    } else {
      $.lastIndex = g;
      const c = $.exec(o);
      if (c) {
        const p = c[0], k = c[1], R = u.create(r, l + g), x = u.create(r, l + g + p.length);
        s.push({
          type: "tag",
          content: k,
          range: f.create(R, x)
        }), g += p.length, g = w(o, g);
      }
      if (g < o.length) {
        const p = o.substring(g), k = Array.from(p.matchAll(A));
        s.push(...W(k, p, r, l + g));
      }
    }
    r++, l = 0;
  }
  return s.length > 0 && s[s.length - 1].type === "break" ? s.slice(0, -1) : s;
}
function W(n, e, t, i) {
  const s = [];
  if (n.length === 0) {
    const r = u.create(t, i), l = u.create(t, i + e.length);
    s.push({
      type: "text",
      content: e,
      range: f.create(r, l)
    });
  } else {
    let r = 0;
    for (const a of n) {
      const h = a.index, d = e.substring(r, h);
      d.length > 0 && s.push({
        type: "text",
        content: e.substring(r, h),
        range: f.create(u.create(t, r + i), u.create(t, h + i))
      });
      let o = d.length + 1;
      const g = a[1];
      if (s.push({
        type: "inline-tag",
        content: g,
        range: f.create(u.create(t, r + o + i), u.create(t, r + o + g.length + i))
      }), o += g.length, a.length === 4) {
        o += a[2].length;
        const m = a[3];
        s.push({
          type: "text",
          content: m,
          range: f.create(u.create(t, r + o + i), u.create(t, r + o + m.length + i))
        });
      } else
        s.push({
          type: "text",
          content: "",
          range: f.create(u.create(t, r + o + i), u.create(t, r + o + i))
        });
      r = h + a[0].length;
    }
    const l = e.substring(r);
    l.length > 0 && s.push({
      type: "text",
      content: l,
      range: f.create(u.create(t, r + i), u.create(t, r + i + l.length))
    });
  }
  return s;
}
const P = /\S/, B = /\s*$/;
function w(n, e) {
  const t = n.substring(e).match(P);
  return t ? e + t.index : n.length;
}
function j(n) {
  const e = n.match(B);
  if (e && typeof e.index == "number")
    return e.index;
}
function G(n) {
  var e, t, i, s;
  const r = u.create(n.position.line, n.position.character);
  if (n.tokens.length === 0)
    return new T([], f.create(r, r));
  const l = [];
  for (; n.index < n.tokens.length; ) {
    const d = U(n, l[l.length - 1]);
    d && l.push(d);
  }
  const a = (t = (e = l[0]) === null || e === void 0 ? void 0 : e.range.start) !== null && t !== void 0 ? t : r, h = (s = (i = l[l.length - 1]) === null || i === void 0 ? void 0 : i.range.end) !== null && s !== void 0 ? s : r;
  return new T(l, f.create(a, h));
}
function U(n, e) {
  const t = n.tokens[n.index];
  if (t.type === "tag")
    return _(n, !1);
  if (t.type === "text" || t.type === "inline-tag")
    return M(n);
  X(t, e), n.index++;
}
function X(n, e) {
  if (e) {
    const t = new J("", n.range);
    "inlines" in e ? e.inlines.push(t) : e.content.inlines.push(t);
  }
}
function M(n) {
  let e = n.tokens[n.index];
  const t = e;
  let i = e;
  const s = [];
  for (; e && e.type !== "break" && e.type !== "tag"; )
    s.push(q(n)), i = e, e = n.tokens[n.index];
  return new b(s, f.create(t.range.start, i.range.end));
}
function q(n) {
  return n.tokens[n.index].type === "inline-tag" ? _(n, !0) : E(n);
}
function _(n, e) {
  const t = n.tokens[n.index++], i = t.content.substring(1), s = n.tokens[n.index];
  if ((s == null ? void 0 : s.type) === "text")
    if (e) {
      const r = E(n);
      return new y(i, new b([r], r.range), e, f.create(t.range.start, r.range.end));
    } else {
      const r = M(n);
      return new y(i, r, e, f.create(t.range.start, r.range.end));
    }
  else {
    const r = t.range;
    return new y(i, new b([], r), e, r);
  }
}
function E(n) {
  const e = n.tokens[n.index++];
  return new J(e.content, e.range);
}
function S(n) {
  if (!n)
    return S({
      start: "/**",
      end: "*/",
      line: "*"
    });
  const { start: e, end: t, line: i } = n;
  return {
    start: v(e, !0),
    end: v(t, !1),
    line: v(i, !0)
  };
}
function v(n, e) {
  if (typeof n == "string" || typeof n == "object") {
    const t = typeof n == "string" ? N(n) : n.source;
    return e ? new RegExp(`^\\s*${t}`) : new RegExp(`\\s*${t}\\s*$`);
  } else
    return n;
}
class T {
  constructor(e, t) {
    this.elements = e, this.range = t;
  }
  getTag(e) {
    return this.getAllTags().find((t) => t.name === e);
  }
  getTags(e) {
    return this.getAllTags().filter((t) => t.name === e);
  }
  getAllTags() {
    return this.elements.filter((e) => "name" in e);
  }
  toString() {
    let e = "";
    for (const t of this.elements)
      if (e.length === 0)
        e = t.toString();
      else {
        const i = t.toString();
        e += D(e) + i;
      }
    return e.trim();
  }
  toMarkdown(e) {
    let t = "";
    for (const i of this.elements)
      if (t.length === 0)
        t = i.toMarkdown(e);
      else {
        const s = i.toMarkdown(e);
        t += D(t) + s;
      }
    return t.trim();
  }
}
class y {
  constructor(e, t, i, s) {
    this.name = e, this.content = t, this.inline = i, this.range = s;
  }
  toString() {
    let e = `@${this.name}`;
    const t = this.content.toString();
    return this.content.inlines.length === 1 ? e = `${e} ${t}` : this.content.inlines.length > 1 && (e = `${e}
${t}`), this.inline ? `{${e}}` : e;
  }
  toMarkdown(e) {
    var t, i;
    return (i = (t = e == null ? void 0 : e.renderTag) === null || t === void 0 ? void 0 : t.call(e, this)) !== null && i !== void 0 ? i : this.toMarkdownDefault(e);
  }
  toMarkdownDefault(e) {
    const t = this.content.toMarkdown(e);
    if (this.inline) {
      const r = F(this.name, t, e ?? {});
      if (typeof r == "string")
        return r;
    }
    let i = "";
    (e == null ? void 0 : e.tag) === "italic" || (e == null ? void 0 : e.tag) === void 0 ? i = "*" : (e == null ? void 0 : e.tag) === "bold" ? i = "**" : (e == null ? void 0 : e.tag) === "bold-italic" && (i = "***");
    let s = `${i}@${this.name}${i}`;
    return this.content.inlines.length === 1 ? s = `${s} — ${t}` : this.content.inlines.length > 1 && (s = `${s}
${t}`), this.inline ? `{${s}}` : s;
  }
}
function F(n, e, t) {
  var i, s;
  if (n === "linkplain" || n === "linkcode" || n === "link") {
    const r = e.indexOf(" ");
    let l = e;
    if (r > 0) {
      const h = w(e, r);
      l = e.substring(h), e = e.substring(0, r);
    }
    return (n === "linkcode" || n === "link" && t.link === "code") && (l = `\`${l}\``), (s = (i = t.renderLink) === null || i === void 0 ? void 0 : i.call(t, e, l)) !== null && s !== void 0 ? s : H(e, l);
  }
}
function H(n, e) {
  try {
    return z.parse(n, !0), `[${e}](${n})`;
  } catch {
    return n;
  }
}
class b {
  constructor(e, t) {
    this.inlines = e, this.range = t;
  }
  toString() {
    let e = "";
    for (let t = 0; t < this.inlines.length; t++) {
      const i = this.inlines[t], s = this.inlines[t + 1];
      e += i.toString(), s && s.range.start.line > i.range.start.line && (e += `
`);
    }
    return e;
  }
  toMarkdown(e) {
    let t = "";
    for (let i = 0; i < this.inlines.length; i++) {
      const s = this.inlines[i], r = this.inlines[i + 1];
      t += s.toMarkdown(e), r && r.range.start.line > s.range.start.line && (t += `
`);
    }
    return t;
  }
}
class J {
  constructor(e, t) {
    this.text = e, this.range = t;
  }
  toString() {
    return this.text;
  }
  toMarkdown() {
    return this.text;
  }
}
function D(n) {
  return n.endsWith(`
`) ? `
` : `

`;
}
export {
  I as isJSDoc,
  Z as parseJSDoc
};
