import { r as c, cpOf as g, throwIfNullish as X, PosixClassNames as U } from "../utils.js";
const C = c`\[\^?`, b = `c.? | C(?:-.?)?|${c`[pP]\{(?:\^?[-\x20_]*[A-Za-z][-\x20\w]*\})?`}|${c`x[89A-Fa-f]\p{AHex}(?:\\x[89A-Fa-f]\p{AHex})*`}|${c`u(?:\p{AHex}{4})? | x\{[^\}]*\}? | x\p{AHex}{0,2}`}|${c`o\{[^\}]*\}?`}|${c`\d{1,3}`}`, k = /[?*+][?+]?|\{(?:\d+(?:,\d*)?|,\d+)\}\??/, m = new RegExp(c`
  \\ (?:
    ${b}
    | [gk]<[^>]*>?
    | [gk]'[^']*'?
    | .
  )
  | \( (?:
    \? (?:
      [:=!>({]
      | <[=!]
      | <[^>]*>
      | '[^']*'
      | ~\|?
      | #(?:[^)\\]|\\.?)*
      | [^:)]*[:)]
    )?
    | \*[^\)]*\)?
  )?
  | (?:${k.source})+
  | ${C}
  | .
`.replace(/\s+/g, ""), "gsu"), x = new RegExp(c`
  \\ (?:
    ${b}
    | .
  )
  | \[:(?:\^?\p{Alpha}+|\^):\]
  | ${C}
  | &&
  | .
`.replace(/\s+/g, ""), "gsu");
function ne(e, n = {}) {
  const r = { flags: "", ...n, rules: { captureGroup: !1, singleline: !1, ...n.rules } };
  if (typeof e != "string") throw new Error("String expected as pattern");
  const o = Y(r.flags), a = [o.extended], s = { captureGroup: r.rules.captureGroup, getCurrentModX() {
    return a.at(-1);
  }, numOpenGroups: 0, popModX() {
    a.pop();
  }, pushModX(u) {
    a.push(u);
  }, replaceCurrentModX(u) {
    a[a.length - 1] = u;
  }, singleline: r.rules.singleline };
  let t = [], i;
  for (m.lastIndex = 0; i = m.exec(e); ) {
    const u = S(s, e, i[0], m.lastIndex);
    u.tokens ? t.push(...u.tokens) : u.token && t.push(u.token), u.lastIndex !== void 0 && (m.lastIndex = u.lastIndex);
  }
  const l = [];
  let p = 0;
  t.filter((u) => u.type === "GroupOpen").forEach((u) => {
    u.kind === "capturing" ? u.number = ++p : u.raw === "(" && l.push(u);
  }), p || l.forEach((u, N) => {
    u.kind = "capturing", u.number = N + 1;
  });
  const d = p || l.length;
  return { tokens: t.map((u) => u.type === "EscapedNumber" ? V(u, d) : u).flat(), flags: o };
}
function S(e, n, r, o) {
  const [a, s] = r;
  if (r === "[" || r === "[^") {
    const t = W(n, r, o);
    return { tokens: t.tokens, lastIndex: t.lastIndex };
  }
  if (a === "\\") {
    if ("AbBGyYzZ".includes(s)) return { token: $(r, r) };
    if (/^\\g[<']/.test(r)) {
      if (!/^\\g(?:<[^>]+>|'[^']+')$/.test(r)) throw new Error(`Invalid group name "${r}"`);
      return { token: F(r) };
    }
    if (/^\\k[<']/.test(r)) {
      if (!/^\\k(?:<[^>]+>|'[^']+')$/.test(r)) throw new Error(`Invalid group name "${r}"`);
      return { token: O(r) };
    }
    if (s === "K") return { token: M("keep", r) };
    if (s === "N" || s === "R") return { token: w("newline", r, { negate: s === "N" }) };
    if (s === "O") return { token: w("any", r) };
    if (s === "X") return { token: w("text_segment", r) };
    const t = v(r, { inCharClass: !1 });
    return Array.isArray(t) ? { tokens: t } : { token: t };
  }
  if (a === "(") {
    if (s === "*") return { token: K(r) };
    if (r === "(?{") throw new Error(`Unsupported callout "${r}"`);
    if (r.startsWith("(?#")) {
      if (n[o] !== ")") throw new Error('Unclosed comment group "(?#"');
      return { lastIndex: o + 1 };
    }
    if (/^\(\?[-imx]+[:)]$/.test(r)) return { token: j(r, e) };
    if (e.pushModX(e.getCurrentModX()), e.numOpenGroups++, r === "(" && !e.captureGroup || r === "(?:") return { token: h("group", r) };
    if (r === "(?>") return { token: h("atomic", r) };
    if (r === "(?=" || r === "(?!" || r === "(?<=" || r === "(?<!") return { token: h(r[2] === "<" ? "lookbehind" : "lookahead", r, { negate: r.endsWith("!") }) };
    if (r === "(" && e.captureGroup || r.startsWith("(?<") && r.endsWith(">") || r.startsWith("(?'") && r.endsWith("'")) return { token: h("capturing", r, { ...r !== "(" && { name: r.slice(3, -1) } }) };
    if (r.startsWith("(?~")) {
      if (r === "(?~|") throw new Error(`Unsupported absence function kind "${r}"`);
      return { token: h("absence_repeater", r) };
    }
    throw r === "(?(" ? new Error(`Unsupported conditional "${r}"`) : new Error(`Invalid or unsupported group option "${r}"`);
  }
  if (r === ")") {
    if (e.popModX(), e.numOpenGroups--, e.numOpenGroups < 0) throw new Error('Unmatched ")"');
    return { token: R(r) };
  }
  if (e.getCurrentModX()) {
    if (r === "#") {
      const t = n.indexOf(`
`, o);
      return { lastIndex: t === -1 ? n.length : t };
    }
    if (/^\s$/.test(r)) {
      const t = /\s+/y;
      return t.lastIndex = o, { lastIndex: t.exec(n) ? t.lastIndex : o };
    }
  }
  if (r === ".") return { token: w("dot", r) };
  if (r === "^" || r === "$") {
    const t = e.singleline ? { "^": c`\A`, $: c`\Z` }[r] : r;
    return { token: $(t, r) };
  }
  return r === "|" ? { token: z(r) } : k.test(r) ? { tokens: ee(r) } : { token: f(g(r), r) };
}
function W(e, n, r) {
  const o = [y(n[1] === "^", n)];
  let a = 1, s;
  for (x.lastIndex = r; s = x.exec(e); ) {
    const t = s[0];
    if (t[0] === "[" && t[1] !== ":") a++, o.push(y(t[1] === "^", t));
    else if (t === "]") {
      if (o.at(-1).type === "CharacterClassOpen") o.push(f(93, t));
      else if (a--, o.push(H(t)), !a) break;
    } else {
      const i = G(t);
      Array.isArray(i) ? o.push(...i) : o.push(i);
    }
  }
  return { tokens: o, lastIndex: x.lastIndex || e.length };
}
function G(e) {
  if (e[0] === "\\") return v(e, { inCharClass: !0 });
  if (e[0] === "[") {
    const n = /\[:(?<negate>\^?)(?<name>[a-z]+):\]/.exec(e);
    if (!n || !U.has(n.groups.name)) throw new Error(`Invalid POSIX class "${e}"`);
    return w("posix", e, { value: n.groups.name, negate: !!n.groups.negate });
  }
  return e === "-" ? P(e) : e === "&&" ? _(e) : f(g(e), e);
}
function v(e, { inCharClass: n }) {
  const r = e[1];
  if (r === "c" || r === "C") return B(e);
  if ("dDhHsSwW".includes(r)) return Q(e);
  if (e.startsWith(c`\o{`)) throw new Error(`Incomplete, invalid, or unsupported octal code point "${e}"`);
  if (/^\\[pP]\{/.test(e)) {
    if (e.length === 3) throw new Error(`Incomplete or invalid Unicode property "${e}"`);
    return q(e);
  }
  if (new RegExp("^\\\\x[89A-Fa-f]\\p{AHex}", "u").test(e)) try {
    const o = e.split(/\\x/).slice(1).map((t) => parseInt(t, 16)), a = new TextDecoder("utf-8", { ignoreBOM: !0, fatal: !0 }).decode(new Uint8Array(o)), s = new TextEncoder();
    return [...a].map((t) => {
      const i = [...s.encode(t)].map((l) => `\\x${l.toString(16)}`).join("");
      return f(g(t), i);
    });
  } catch {
    throw new Error(`Multibyte code "${e}" incomplete or invalid in Oniguruma`);
  }
  if (r === "u" || r === "x") return f(J(e), e);
  if (E.has(r)) return f(E.get(r), e);
  if (/\d/.test(r)) return Z(n, e);
  if (e === "\\") throw new Error(c`Incomplete escape "\"`);
  if (r === "M") throw new Error(`Unsupported meta "${e}"`);
  if ([...e].length === 2) return f(e.codePointAt(1), e);
  throw new Error(`Unexpected escape "${e}"`);
}
function z(e) {
  return { type: "Alternator", raw: e };
}
function $(e, n) {
  return { type: "Assertion", kind: e, raw: n };
}
function O(e) {
  return { type: "Backreference", raw: e };
}
function f(e, n) {
  return { type: "Character", value: e, raw: n };
}
function H(e) {
  return { type: "CharacterClassClose", raw: e };
}
function P(e) {
  return { type: "CharacterClassHyphen", raw: e };
}
function _(e) {
  return { type: "CharacterClassIntersector", raw: e };
}
function y(e, n) {
  return { type: "CharacterClassOpen", negate: e, raw: n };
}
function w(e, n, r = {}) {
  return { type: "CharacterSet", kind: e, ...r, raw: n };
}
function M(e, n, r = {}) {
  return e === "keep" ? { type: "Directive", kind: e, raw: n } : { type: "Directive", kind: e, flags: X(r.flags), raw: n };
}
function Z(e, n) {
  return { type: "EscapedNumber", inCharClass: e, raw: n };
}
function R(e) {
  return { type: "GroupClose", raw: e };
}
function h(e, n, r = {}) {
  return { type: "GroupOpen", kind: e, ...r, raw: n };
}
function T(e, n, r, o) {
  return { type: "NamedCallout", kind: e, tag: n, arguments: r, raw: o };
}
function D(e, n, r, o) {
  return { type: "Quantifier", kind: e, min: n, max: r, raw: o };
}
function F(e) {
  return { type: "Subroutine", raw: e };
}
const L = /* @__PURE__ */ new Set(["COUNT", "CMP", "ERROR", "FAIL", "MAX", "MISMATCH", "SKIP", "TOTAL_COUNT"]), E = /* @__PURE__ */ new Map([["a", 7], ["b", 8], ["e", 27], ["f", 12], ["n", 10], ["r", 13], ["t", 9], ["v", 11]]);
function B(e) {
  const n = e[1] === "c" ? e[2] : e[3];
  if (!n || !/[A-Za-z]/.test(n)) throw new Error(`Unsupported control character "${e}"`);
  return f(g(n.toUpperCase()) - 64, e);
}
function j(e, n) {
  let { on: r, off: o } = /^\(\?(?<on>[imx]*)(?:-(?<off>[-imx]*))?/.exec(e).groups;
  o ?? (o = "");
  const a = (n.getCurrentModX() || r.includes("x")) && !o.includes("x"), s = I(r), t = I(o), i = {};
  if (s && (i.enable = s), t && (i.disable = t), e.endsWith(")")) return n.replaceCurrentModX(a), M("flags", e, { flags: i });
  if (e.endsWith(":")) return n.pushModX(a), n.numOpenGroups++, h("group", e, { ...(s || t) && { flags: i } });
  throw new Error(`Unexpected flag modifier "${e}"`);
}
function K(e) {
  const n = /\(\*(?<name>[A-Za-z_]\w*)?(?:\[(?<tag>(?:[A-Za-z_]\w*)?)\])?(?:\{(?<args>[^}]*)\})?\)/.exec(e);
  if (!n) throw new Error(`Incomplete or invalid named callout "${e}"`);
  const { name: r, tag: o, args: a } = n.groups;
  if (!r) throw new Error(`Invalid named callout "${e}"`);
  if (o === "") throw new Error(`Named callout tag with empty value not allowed "${e}"`);
  const s = a ? a.split(",").filter((d) => d !== "").map((d) => /^[+-]?\d+$/.test(d) ? +d : d) : [], [t, i, l] = s, p = L.has(r) ? r.toLowerCase() : "custom";
  switch (p) {
    case "fail":
    case "mismatch":
    case "skip":
      if (s.length > 0) throw new Error(`Named callout arguments not allowed "${s}"`);
      break;
    case "error":
      if (s.length > 1) throw new Error(`Named callout allows only one argument "${s}"`);
      if (typeof t == "string") throw new Error(`Named callout argument must be a number "${t}"`);
      break;
    case "max":
      if (!s.length || s.length > 2) throw new Error(`Named callout must have one or two arguments "${s}"`);
      if (typeof t == "string" && !/^[A-Za-z_]\w*$/.test(t)) throw new Error(`Named callout argument one must be a tag or number "${t}"`);
      if (s.length === 2 && (typeof i == "number" || !/^[<>X]$/.test(i))) throw new Error(`Named callout optional argument two must be '<', '>', or 'X' "${i}"`);
      break;
    case "count":
    case "total_count":
      if (s.length > 1) throw new Error(`Named callout allows only one argument "${s}"`);
      if (s.length === 1 && (typeof t == "number" || !/^[<>X]$/.test(t))) throw new Error(`Named callout optional argument must be '<', '>', or 'X' "${t}"`);
      break;
    case "cmp":
      if (s.length !== 3) throw new Error(`Named callout must have three arguments "${s}"`);
      if (typeof t == "string" && !/^[A-Za-z_]\w*$/.test(t)) throw new Error(`Named callout argument one must be a tag or number "${t}"`);
      if (typeof i == "number" || !/^(?:[<>!=]=|[<>])$/.test(i)) throw new Error(`Named callout argument two must be '==', '!=', '>', '<', '>=', or '<=' "${i}"`);
      if (typeof l == "string" && !/^[A-Za-z_]\w*$/.test(l)) throw new Error(`Named callout argument three must be a tag or number "${l}"`);
      break;
    case "custom":
      throw new Error(`Undefined callout name "${r}"`);
    default:
      throw new Error(`Unexpected named callout kind "${p}"`);
  }
  return T(p, o ?? null, (a == null ? void 0 : a.split(",")) ?? null, e);
}
function A(e) {
  let n = null, r, o;
  if (e[0] === "{") {
    const { minStr: a, maxStr: s } = /^\{(?<minStr>\d*)(?:,(?<maxStr>\d*))?/.exec(e).groups, t = 1e5;
    if (+a > t || s && +s > t) throw new Error("Quantifier value unsupported in Oniguruma");
    if (r = +a, o = s === void 0 ? +a : s === "" ? 1 / 0 : +s, r > o && (n = "possessive", [r, o] = [o, r]), e.endsWith("?")) {
      if (n === "possessive") throw new Error('Unsupported possessive interval quantifier chain with "?"');
      n = "lazy";
    } else n || (n = "greedy");
  } else r = e[0] === "+" ? 1 : 0, o = e[0] === "?" ? 1 : 1 / 0, n = e[1] === "+" ? "possessive" : e[1] === "?" ? "lazy" : "greedy";
  return D(n, r, o, e);
}
function Q(e) {
  const n = e[1].toLowerCase();
  return w({ d: "digit", h: "hex", s: "space", w: "word" }[n], e, { negate: e[1] !== n });
}
function q(e) {
  const { p: n, neg: r, value: o } = /^\\(?<p>[pP])\{(?<neg>\^?)(?<value>[^}]+)/.exec(e).groups;
  return w("property", e, { value: o, negate: n === "P" && !r || n === "p" && !!r });
}
function I(e) {
  const n = {};
  return e.includes("i") && (n.ignoreCase = !0), e.includes("m") && (n.dotAll = !0), e.includes("x") && (n.extended = !0), Object.keys(n).length ? n : null;
}
function Y(e) {
  const n = { ignoreCase: !1, dotAll: !1, extended: !1, digitIsAscii: !1, posixIsAscii: !1, spaceIsAscii: !1, wordIsAscii: !1, textSegmentMode: null };
  for (let r = 0; r < e.length; r++) {
    const o = e[r];
    if (!"imxDPSWy".includes(o)) throw new Error(`Invalid flag "${o}"`);
    if (o === "y") {
      if (!/^y{[gw]}/.test(e.slice(r))) throw new Error('Invalid or unspecified flag "y" mode');
      n.textSegmentMode = e[r + 2] === "g" ? "grapheme" : "word", r += 3;
      continue;
    }
    n[{ i: "ignoreCase", m: "dotAll", x: "extended", D: "digitIsAscii", P: "posixIsAscii", S: "spaceIsAscii", W: "wordIsAscii" }[o]] = !0;
  }
  return n;
}
function J(e) {
  if (new RegExp("^(?:\\\\u(?!\\p{AHex}{4})|\\\\x(?!\\p{AHex}{1,2}|\\{\\p{AHex}{1,8}\\}))", "u").test(e)) throw new Error(`Incomplete or invalid escape "${e}"`);
  const n = e[2] === "{" ? new RegExp("^\\\\x\\{\\s*(?<hex>\\p{AHex}+)", "u").exec(e).groups.hex : e.slice(2);
  return parseInt(n, 16);
}
function V(e, n) {
  const { raw: r, inCharClass: o } = e, a = r.slice(1);
  if (!o && (a !== "0" && a.length === 1 || a[0] !== "0" && +a <= n)) return [O(r)];
  const s = [], t = a.match(/^[0-7]+|\d/g);
  for (let i = 0; i < t.length; i++) {
    const l = t[i];
    let p;
    if (i === 0 && l !== "8" && l !== "9") {
      if (p = parseInt(l, 8), p > 127) throw new Error(c`Octal encoded byte above 177 unsupported "${r}"`);
    } else p = g(l);
    s.push(f(p, (i === 0 ? "\\" : "") + l));
  }
  return s;
}
function ee(e) {
  const n = [], r = new RegExp(k, "gy");
  let o;
  for (; o = r.exec(e); ) {
    const a = o[0];
    if (a[0] === "{") {
      const s = /^\{(?<min>\d+),(?<max>\d+)\}\??$/.exec(a);
      if (s) {
        const { min: t, max: i } = s.groups;
        if (+t > +i && a.endsWith("?")) {
          r.lastIndex--, n.push(A(a.slice(0, -1)));
          continue;
        }
      }
    }
    n.push(A(a));
  }
  return n;
}
export {
  ne as tokenize
};
