import { possiblePathsFrom as P } from "./interpreter.js";
import { RestWalker as K } from "./rest.js";
import { tokenStructuredMatcherNoCategories as M, tokenStructuredMatcher as L } from "../../scan/tokens.js";
import { Option as j, Repetition as b, RepetitionMandatory as q, RepetitionMandatoryWithSeparator as U, RepetitionWithSeparator as V, Alternation as C, Alternative as y } from "../../../../../../../@chevrotain_gast@11.0.3/node_modules/@chevrotain/gast/lib/src/model.js";
import { GAstVisitor as G } from "../../../../../../../@chevrotain_gast@11.0.3/node_modules/@chevrotain/gast/lib/src/visitor.js";
import O from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/every.js";
import p from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/map.js";
import N from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/isEmpty.js";
import k from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/forEach.js";
import S from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/flatten.js";
import W from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/reduce.js";
import x from "../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/has.js";
var h;
(function(e) {
  e[e.OPTION = 0] = "OPTION", e[e.REPETITION = 1] = "REPETITION", e[e.REPETITION_MANDATORY = 2] = "REPETITION_MANDATORY", e[e.REPETITION_MANDATORY_WITH_SEPARATOR = 3] = "REPETITION_MANDATORY_WITH_SEPARATOR", e[e.REPETITION_WITH_SEPARATOR = 4] = "REPETITION_WITH_SEPARATOR", e[e.ALTERNATION = 5] = "ALTERNATION";
})(h || (h = {}));
function z(e) {
  if (e instanceof j || e === "Option")
    return h.OPTION;
  if (e instanceof b || e === "Repetition")
    return h.REPETITION;
  if (e instanceof q || e === "RepetitionMandatory")
    return h.REPETITION_MANDATORY;
  if (e instanceof U || e === "RepetitionMandatoryWithSeparator")
    return h.REPETITION_MANDATORY_WITH_SEPARATOR;
  if (e instanceof V || e === "RepetitionWithSeparator")
    return h.REPETITION_WITH_SEPARATOR;
  if (e instanceof C || e === "Alternation")
    return h.ALTERNATION;
  throw Error("non exhaustive match");
}
function at(e) {
  const { occurrence: t, rule: n, prodType: r, maxLookahead: s } = e, c = z(r);
  return c === h.ALTERNATION ? F(t, n, s) : D(t, n, c, s);
}
function ht(e, t, n, r, s, c) {
  const i = F(e, t, n), a = H(i) ? M : L;
  return c(i, r, a, s);
}
function ft(e, t, n, r, s, c) {
  const i = D(e, t, s, n), a = H(i) ? M : L;
  return c(i[0], a, r);
}
function ut(e, t, n, r) {
  const s = e.length, c = O(e, (i) => O(i, (a) => a.length === 1));
  if (t)
    return function(i) {
      const a = p(i, (o) => o.GATE);
      for (let o = 0; o < s; o++) {
        const f = e[o], u = f.length, l = a[o];
        if (!(l !== void 0 && l.call(this) === !1))
          t: for (let T = 0; T < u; T++) {
            const I = f[T], E = I.length;
            for (let A = 0; A < E; A++) {
              const g = this.LA(A + 1);
              if (n(g, I[A]) === !1)
                continue t;
            }
            return o;
          }
      }
    };
  if (c && !r) {
    const i = p(e, (o) => S(o)), a = W(i, (o, f, u) => (k(f, (l) => {
      x(o, l.tokenTypeIdx) || (o[l.tokenTypeIdx] = u), k(l.categoryMatches, (T) => {
        x(o, T) || (o[T] = u);
      });
    }), o), {});
    return function() {
      const o = this.LA(1);
      return a[o.tokenTypeIdx];
    };
  } else
    return function() {
      for (let i = 0; i < s; i++) {
        const a = e[i], o = a.length;
        t: for (let f = 0; f < o; f++) {
          const u = a[f], l = u.length;
          for (let T = 0; T < l; T++) {
            const I = this.LA(T + 1);
            if (n(I, u[T]) === !1)
              continue t;
          }
          return i;
        }
      }
    };
}
function lt(e, t, n) {
  const r = O(e, (c) => c.length === 1), s = e.length;
  if (r && !n) {
    const c = S(e);
    if (c.length === 1 && N(c[0].categoryMatches)) {
      const a = c[0].tokenTypeIdx;
      return function() {
        return this.LA(1).tokenTypeIdx === a;
      };
    } else {
      const i = W(c, (a, o, f) => (a[o.tokenTypeIdx] = !0, k(o.categoryMatches, (u) => {
        a[u] = !0;
      }), a), []);
      return function() {
        const a = this.LA(1);
        return i[a.tokenTypeIdx] === !0;
      };
    }
  } else
    return function() {
      t: for (let c = 0; c < s; c++) {
        const i = e[c], a = i.length;
        for (let o = 0; o < a; o++) {
          const f = this.LA(o + 1);
          if (t(f, i[o]) === !1)
            continue t;
        }
        return !0;
      }
      return !1;
    };
}
class B extends K {
  constructor(t, n, r) {
    super(), this.topProd = t, this.targetOccurrence = n, this.targetProdType = r;
  }
  startWalking() {
    return this.walk(this.topProd), this.restDef;
  }
  checkIsTarget(t, n, r, s) {
    return t.idx === this.targetOccurrence && this.targetProdType === n ? (this.restDef = r.concat(s), !0) : !1;
  }
  walkOption(t, n, r) {
    this.checkIsTarget(t, h.OPTION, n, r) || super.walkOption(t, n, r);
  }
  walkAtLeastOne(t, n, r) {
    this.checkIsTarget(t, h.REPETITION_MANDATORY, n, r) || super.walkOption(t, n, r);
  }
  walkAtLeastOneSep(t, n, r) {
    this.checkIsTarget(t, h.REPETITION_MANDATORY_WITH_SEPARATOR, n, r) || super.walkOption(t, n, r);
  }
  walkMany(t, n, r) {
    this.checkIsTarget(t, h.REPETITION, n, r) || super.walkOption(t, n, r);
  }
  walkManySep(t, n, r) {
    this.checkIsTarget(t, h.REPETITION_WITH_SEPARATOR, n, r) || super.walkOption(t, n, r);
  }
}
class _ extends G {
  constructor(t, n, r) {
    super(), this.targetOccurrence = t, this.targetProdType = n, this.targetRef = r, this.result = [];
  }
  checkIsTarget(t, n) {
    t.idx === this.targetOccurrence && this.targetProdType === n && (this.targetRef === void 0 || t === this.targetRef) && (this.result = t.definition);
  }
  visitOption(t) {
    this.checkIsTarget(t, h.OPTION);
  }
  visitRepetition(t) {
    this.checkIsTarget(t, h.REPETITION);
  }
  visitRepetitionMandatory(t) {
    this.checkIsTarget(t, h.REPETITION_MANDATORY);
  }
  visitRepetitionMandatoryWithSeparator(t) {
    this.checkIsTarget(t, h.REPETITION_MANDATORY_WITH_SEPARATOR);
  }
  visitRepetitionWithSeparator(t) {
    this.checkIsTarget(t, h.REPETITION_WITH_SEPARATOR);
  }
  visitAlternation(t) {
    this.checkIsTarget(t, h.ALTERNATION);
  }
}
function m(e) {
  const t = new Array(e);
  for (let n = 0; n < e; n++)
    t[n] = [];
  return t;
}
function R(e) {
  let t = [""];
  for (let n = 0; n < e.length; n++) {
    const r = e[n], s = [];
    for (let c = 0; c < t.length; c++) {
      const i = t[c];
      s.push(i + "_" + r.tokenTypeIdx);
      for (let a = 0; a < r.categoryMatches.length; a++) {
        const o = "_" + r.categoryMatches[a];
        s.push(i + o);
      }
    }
    t = s;
  }
  return t;
}
function J(e, t, n) {
  for (let r = 0; r < e.length; r++) {
    if (r === n)
      continue;
    const s = e[r];
    for (let c = 0; c < t.length; c++) {
      const i = t[c];
      if (s[i] === !0)
        return !1;
    }
  }
  return !0;
}
function w(e, t) {
  const n = p(e, (i) => P([i], 1)), r = m(n.length), s = p(n, (i) => {
    const a = {};
    return k(i, (o) => {
      const f = R(o.partialPath);
      k(f, (u) => {
        a[u] = !0;
      });
    }), a;
  });
  let c = n;
  for (let i = 1; i <= t; i++) {
    const a = c;
    c = m(a.length);
    for (let o = 0; o < a.length; o++) {
      const f = a[o];
      for (let u = 0; u < f.length; u++) {
        const l = f[u].partialPath, T = f[u].suffixDef, I = R(l);
        if (J(s, I, o) || N(T) || l.length === t) {
          const A = r[o];
          if (Q(A, l) === !1) {
            A.push(l);
            for (let g = 0; g < I.length; g++) {
              const d = I[g];
              s[o][d] = !0;
            }
          }
        } else {
          const A = P(T, i + 1, l);
          c[o] = c[o].concat(A), k(A, (g) => {
            const d = R(g.partialPath);
            k(d, (v) => {
              s[o][v] = !0;
            });
          });
        }
      }
    }
  }
  return r;
}
function F(e, t, n, r) {
  const s = new _(e, h.ALTERNATION, r);
  return t.accept(s), w(s.result, n);
}
function D(e, t, n, r) {
  const s = new _(e, n);
  t.accept(s);
  const c = s.result, a = new B(t, e, n).startWalking(), o = new y({ definition: c }), f = new y({ definition: a });
  return w([o, f], r);
}
function Q(e, t) {
  t: for (let n = 0; n < e.length; n++) {
    const r = e[n];
    if (r.length === t.length) {
      for (let s = 0; s < r.length; s++) {
        const c = t[s], i = r[s];
        if ((c === i || i.categoryMatchesMap[c.tokenTypeIdx] !== void 0) === !1)
          continue t;
      }
      return !0;
    }
  }
  return !1;
}
function Tt(e, t) {
  return e.length < t.length && O(e, (n, r) => {
    const s = t[r];
    return n === s || s.categoryMatchesMap[n.tokenTypeIdx];
  });
}
function H(e) {
  return O(e, (t) => O(t, (n) => O(n, (r) => N(r.categoryMatches))));
}
export {
  h as PROD_TYPE,
  H as areTokenCategoriesNotUsed,
  ut as buildAlternativesLookAheadFunc,
  ft as buildLookaheadFuncForOptionalProd,
  ht as buildLookaheadFuncForOr,
  lt as buildSingleAlternativeLookaheadFunction,
  Q as containsPath,
  at as getLookaheadPaths,
  D as getLookaheadPathsForOptionalProd,
  F as getLookaheadPathsForOr,
  z as getProdType,
  Tt as isStrictPrefixOfPath,
  w as lookAheadSequenceFromAlternatives
};
