import e from "../../lodash-es/isEmpty.js";
import { Alternation as t, NonTerminal as n, Option as r, Repetition as i, RepetitionMandatory as a, RepetitionMandatoryWithSeparator as o, RepetitionWithSeparator as s, Terminal as c } from "../../@chevrotain/gast/lib/src/model.js";
import { tokenLabel as l, tokenMatcher as u } from "../../chevrotain/lib/src/scan/tokens_public.js";
import { getLookaheadPaths as d } from "../../chevrotain/lib/src/parse/grammar/lookahead.js";
import { LLkLookaheadStrategy as f } from "../../chevrotain/lib/src/parse/grammar/llk_lookahead.js";
import "../../chevrotain/lib/src/api.js";
import p from "../../lodash-es/map.js";
import { AtomTransition as m, EpsilonTransition as h, RuleTransition as g, buildATNKey as _, createATN as v } from "./atn.js";
import { ATNConfigSet as y, DFA_ERROR as b, getATNConfigKey as x } from "./dfa.js";
import S from "../../lodash-es/min.js";
import C from "../../lodash-es/flatMap.js";
import w from "../../lodash-es/uniqBy.js";
import T from "../../lodash-es/flatten.js";
import E from "../../lodash-es/forEach.js";
import D from "../../lodash-es/reduce.js";
//#region ../../node_modules/chevrotain-allstar/lib/all-star-lookahead.js
function O(e, t) {
	let n = {};
	return (r) => {
		let i = r.toString(), a = n[i];
		return a === void 0 ? (a = {
			atnStartState: e,
			decision: t,
			states: {}
		}, n[i] = a, a) : a;
	};
}
var k = class {
	constructor() {
		this.predicates = [];
	}
	is(e) {
		return e >= this.predicates.length || this.predicates[e];
	}
	set(e, t) {
		this.predicates[e] = t;
	}
	toString() {
		let e = "", t = this.predicates.length;
		for (let n = 0; n < t; n++) e += this.predicates[n] === !0 ? "1" : "0";
		return e;
	}
}, A = new k(), j = class extends f {
	constructor(e) {
		super(), this.logging = e?.logging ?? ((e) => console.log(e));
	}
	initialize(e) {
		this.atn = v(e.rules), this.dfas = N(this.atn);
	}
	validateAmbiguousAlternationAlternatives() {
		return [];
	}
	validateEmptyOrAlternatives() {
		return [];
	}
	buildLookaheadForAlternation(e) {
		let { prodOccurrence: t, rule: n, hasPredicates: r, dynamicTokensEnabled: i } = e, a = this.dfas, o = this.logging, s = _(n, "Alternation", t), c = this.atn.decisionMap[s].decision, l = p(d({
			maxLookahead: 1,
			occurrence: t,
			prodType: "Alternation",
			rule: n
		}), (e) => p(e, (e) => e[0]));
		if (M(l, !1) && !i) {
			let e = D(l, (e, t, n) => (E(t, (t) => {
				t && (e[t.tokenTypeIdx] = n, E(t.categoryMatches, (t) => {
					e[t] = n;
				}));
			}), e), {});
			return r ? function(t) {
				let n = e[this.LA_FAST(1).tokenTypeIdx];
				if (t !== void 0 && n !== void 0) {
					let e = t[n]?.GATE;
					if (e !== void 0 && e.call(this) === !1) return;
				}
				return n;
			} : function() {
				return e[this.LA_FAST(1).tokenTypeIdx];
			};
		} else if (r) return function(e) {
			let t = new k(), n = e === void 0 ? 0 : e.length;
			for (let r = 0; r < n; r++) {
				let n = e?.[r].GATE;
				t.set(r, n === void 0 || n.call(this));
			}
			let r = P.call(this, a, c, t, o);
			return typeof r == "number" ? r : void 0;
		};
		else return function() {
			let e = P.call(this, a, c, A, o);
			return typeof e == "number" ? e : void 0;
		};
	}
	buildLookaheadForOptional(t) {
		let { prodOccurrence: n, rule: r, prodType: i, dynamicTokensEnabled: a } = t, o = this.dfas, s = this.logging, c = _(r, i, n), l = this.atn.decisionMap[c].decision, u = p(d({
			maxLookahead: 1,
			occurrence: n,
			prodType: i,
			rule: r
		}), (e) => p(e, (e) => e[0]));
		if (M(u) && u[0][0] && !a) {
			let t = u[0], n = T(t);
			if (n.length === 1 && e(n[0].categoryMatches)) {
				let e = n[0].tokenTypeIdx;
				return function() {
					return this.LA_FAST(1).tokenTypeIdx === e;
				};
			} else {
				let e = D(n, (e, t) => (t !== void 0 && (e[t.tokenTypeIdx] = !0, E(t.categoryMatches, (t) => {
					e[t] = !0;
				})), e), {});
				return function() {
					return e[this.LA_FAST(1).tokenTypeIdx] === !0;
				};
			}
		}
		return function() {
			let e = P.call(this, o, l, A, s);
			return typeof e == "object" ? !1 : e === 0;
		};
	}
};
function M(e, t = !0) {
	let n = /* @__PURE__ */ new Set();
	for (let r of e) {
		let e = /* @__PURE__ */ new Set();
		for (let i of r) {
			if (i === void 0) {
				if (t) break;
				return !1;
			}
			let r = [i.tokenTypeIdx].concat(i.categoryMatches);
			for (let t of r) if (n.has(t)) {
				if (!e.has(t)) return !1;
			} else n.add(t), e.add(t);
		}
	}
	return !0;
}
function N(e) {
	let t = e.decisionStates.length, n = Array(t);
	for (let r = 0; r < t; r++) n[r] = O(e.decisionStates[r], r);
	return n;
}
function P(e, t, n, r) {
	let i = e[t](n), a = i.start;
	return a === void 0 && (a = q(i, G(J(i.atnStartState))), i.start = a), F.apply(this, [
		i,
		a,
		n,
		r
	]);
}
function F(e, t, n, r) {
	let i = t, a = 1, o = [], s = this.LA_FAST(a++);
	for (;;) {
		let t = V(i, s);
		if (t === void 0 && (t = I.apply(this, [
			e,
			i,
			s,
			a,
			n,
			r
		])), t === b) return B(o, i, s);
		if (t.isAcceptState === !0) return t.prediction;
		i = t, o.push(s), s = this.LA(a++);
	}
}
function I(e, t, n, r, i, a) {
	let o = H(t.configs, n, i);
	if (o.size === 0) return K(e, t, n, b), b;
	let s = G(o), c = W(o, i);
	if (c !== void 0) s.isAcceptState = !0, s.prediction = c, s.configs.uniqueAlt = c;
	else if ($(o)) {
		let t = S(o.alts);
		s.isAcceptState = !0, s.prediction = t, s.configs.uniqueAlt = t, L.apply(this, [
			e,
			r,
			o.alts,
			a
		]);
	}
	return s = K(e, t, n, s), s;
}
function L(e, t, n, r) {
	let i = [];
	for (let e = 1; e <= t; e++) i.push(this.LA(e).tokenType);
	let a = e.atnStartState, o = a.rule, s = a.production;
	r(R({
		topLevelRule: o,
		ambiguityIndices: n,
		production: s,
		prefixPath: i
	}));
}
function R(e) {
	let t = p(e.prefixPath, (e) => l(e)).join(", "), n = e.production.idx === 0 ? "" : e.production.idx, r = `Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(", ")}> in <${z(e.production)}${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\n`;
	return r += "See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.", r;
}
function z(e) {
	if (e instanceof n) return "SUBRULE";
	if (e instanceof r) return "OPTION";
	if (e instanceof t) return "OR";
	if (e instanceof a) return "AT_LEAST_ONE";
	if (e instanceof o) return "AT_LEAST_ONE_SEP";
	if (e instanceof s) return "MANY_SEP";
	if (e instanceof i) return "MANY";
	if (e instanceof c) return "CONSUME";
	throw Error("non exhaustive match");
}
function B(e, t, n) {
	return {
		actualToken: n,
		possibleTokenTypes: w(C(t.configs.elements, (e) => e.state.transitions).filter((e) => e instanceof m).map((e) => e.tokenType), (e) => e.tokenTypeIdx),
		tokenPath: e
	};
}
function V(e, t) {
	return e.edges[t.tokenTypeIdx];
}
function H(e, t, n) {
	let r = new y(), i = [];
	for (let a of e.elements) {
		if (n.is(a.alt) === !1) continue;
		if (a.state.type === 7) {
			i.push(a);
			continue;
		}
		let e = a.state.transitions.length;
		for (let n = 0; n < e; n++) {
			let e = a.state.transitions[n], i = U(e, t);
			i !== void 0 && r.add({
				state: i,
				alt: a.alt,
				stack: a.stack
			});
		}
	}
	let a;
	if (i.length === 0 && r.size === 1 && (a = r), a === void 0) {
		a = new y();
		for (let e of r.elements) Y(e, a);
	}
	if (i.length > 0 && !Z(a)) for (let e of i) a.add(e);
	return a;
}
function U(e, t) {
	if (e instanceof m && u(t, e.tokenType)) return e.target;
}
function W(e, t) {
	let n;
	for (let r of e.elements) if (t.is(r.alt) === !0) {
		if (n === void 0) n = r.alt;
		else if (n !== r.alt) return;
	}
	return n;
}
function G(e) {
	return {
		configs: e,
		edges: {},
		isAcceptState: !1,
		prediction: -1
	};
}
function K(e, t, n, r) {
	return r = q(e, r), t.edges[n.tokenTypeIdx] = r, r;
}
function q(e, t) {
	if (t === b) return t;
	let n = t.configs.key, r = e.states[n];
	return r === void 0 ? (t.configs.finalize(), e.states[n] = t, t) : r;
}
function J(e) {
	let t = new y(), n = e.transitions.length;
	for (let r = 0; r < n; r++) Y({
		state: e.transitions[r].target,
		alt: r,
		stack: []
	}, t);
	return t;
}
function Y(e, t) {
	let n = e.state;
	if (n.type === 7) {
		if (e.stack.length > 0) {
			let n = [...e.stack];
			Y({
				state: n.pop(),
				alt: e.alt,
				stack: n
			}, t);
		} else t.add(e);
		return;
	}
	n.epsilonOnlyTransitions || t.add(e);
	let r = n.transitions.length;
	for (let i = 0; i < r; i++) {
		let r = n.transitions[i], a = X(e, r);
		a !== void 0 && Y(a, t);
	}
}
function X(e, t) {
	if (t instanceof h) return {
		state: t.target,
		alt: e.alt,
		stack: e.stack
	};
	if (t instanceof g) {
		let n = [...e.stack, t.followState];
		return {
			state: t.target,
			alt: e.alt,
			stack: n
		};
	}
}
function Z(e) {
	for (let t of e.elements) if (t.state.type === 7) return !0;
	return !1;
}
function Q(e) {
	for (let t of e.elements) if (t.state.type !== 7) return !1;
	return !0;
}
function $(e) {
	if (Q(e)) return !0;
	let t = ee(e.elements);
	return te(t) && !ne(t);
}
function ee(e) {
	let t = /* @__PURE__ */ new Map();
	for (let n of e) {
		let e = x(n, !1), r = t.get(e);
		r === void 0 && (r = {}, t.set(e, r)), r[n.alt] = !0;
	}
	return t;
}
function te(e) {
	for (let t of Array.from(e.values())) if (Object.keys(t).length > 1) return !0;
	return !1;
}
function ne(e) {
	for (let t of Array.from(e.values())) if (Object.keys(t).length === 1) return !0;
	return !1;
}
//#endregion
export { j as LLStarLookaheadStrategy };
