import { BaseRegExpVisitor as e } from "../../../../@chevrotain/regexp-to-ast/lib/src/base-regexp-visitor.js";
import "../../../../@chevrotain/regexp-to-ast/lib/src/api.js";
import { PRINT_ERROR as t, PRINT_WARNING as n } from "../../../../@chevrotain/utils/lib/src/print.js";
import { getRegExpAst as r } from "./reg_exp_parser.js";
import { charCodeToOptimizedIndex as i } from "./lexer.js";
//#region ../../node_modules/chevrotain/lib/src/scan/reg_exp.js
var a = "Complement Sets are not supported for first char optimization", o = "Unable to use \"first char\" lexer optimizations:\n";
function s(e, i = !1) {
	try {
		let t = r(e);
		return c(t.value, {}, t.flags.ignoreCase);
	} catch (r) {
		/* istanbul ignore next */
		if (r.message === a) i && n(`${o}\tUnable to optimize: < ${e.toString()} >\n	Complement Sets cannot be automatically optimized.
	This will disable the lexer's first char optimizations.
	See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);
		else {
			let n = "";
			i && (n = "\n	This will disable the lexer's first char optimizations.\n	See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details."), t(`${o}\n\tFailed parsing: < ${e.toString()} >\n\tUsing the @chevrotain/regexp-to-ast library\n	Please open an issue at: https://github.com/chevrotain/chevrotain/issues` + n);
		}
	}
	return [];
}
function c(e, t, n) {
	switch (e.type) {
		case "Disjunction":
			for (let r = 0; r < e.value.length; r++) c(e.value[r], t, n);
			break;
		case "Alternative":
			let r = e.value;
			for (let e = 0; e < r.length; e++) {
				let o = r[e];
				switch (o.type) {
					case "EndAnchor":
					case "GroupBackReference":
					case "Lookahead":
					case "NegativeLookahead":
					case "Lookbehind":
					case "NegativeLookbehind":
					case "StartAnchor":
					case "WordBoundary":
					case "NonWordBoundary": continue;
				}
				let s = o;
				switch (s.type) {
					case "Character":
						l(s.value, t, n);
						break;
					case "Set":
						if (s.complement === !0) throw Error(a);
						s.value.forEach((e) => {
							if (typeof e == "number") l(e, t, n);
							else {
								let r = e;
								if (n === !0) for (let e = r.from; e <= r.to; e++) l(e, t, n);
								else {
									for (let e = r.from; e <= r.to && e < 256; e++) l(e, t, n);
									if (r.to >= 256) {
										let e = r.from >= 256 ? r.from : 256, n = r.to, a = i(e), o = i(n);
										for (let e = a; e <= o; e++) t[e] = e;
									}
								}
							}
						});
						break;
					case "Group":
						c(s.value, t, n);
						break;
					/* istanbul ignore next */
					default: throw Error("Non Exhaustive Match");
				}
				let u = s.quantifier !== void 0 && s.quantifier.atLeast === 0;
				if (s.type === "Group" && f(s) === !1 || s.type !== "Group" && u === !1) break;
			}
			break;
		/* istanbul ignore next */
		default: throw Error("non exhaustive match!");
	}
	return Object.values(t);
}
function l(e, t, n) {
	let r = i(e);
	t[r] = r, n === !0 && u(e, t);
}
function u(e, t) {
	let n = String.fromCharCode(e), r = n.toUpperCase();
	/* istanbul ignore else */
	if (r !== n) {
		let e = i(r.charCodeAt(0));
		t[e] = e;
	} else {
		let e = n.toLowerCase();
		if (e !== n) {
			let n = i(e.charCodeAt(0));
			t[n] = n;
		}
	}
}
function d(e, t) {
	return e.value.find((e) => {
		if (typeof e == "number") return t.includes(e);
		{
			let n = e;
			return t.find((e) => n.from <= e && e <= n.to) !== void 0;
		}
	});
}
function f(e) {
	let t = e.quantifier;
	return t && t.atLeast === 0 ? !0 : e.value ? Array.isArray(e.value) ? e.value.every(f) : f(e.value) : !1;
}
var p = class extends e {
	constructor(e) {
		super(), this.targetCharCodes = e, this.found = !1;
	}
	visitChildren(e) {
		if (this.found !== !0) {
			switch (e.type) {
				case "Lookahead":
					this.visitLookahead(e);
					return;
				case "NegativeLookahead":
					this.visitNegativeLookahead(e);
					return;
				case "Lookbehind":
					this.visitLookbehind(e);
					return;
				case "NegativeLookbehind":
					this.visitNegativeLookbehind(e);
					return;
			}
			super.visitChildren(e);
		}
	}
	visitCharacter(e) {
		this.targetCharCodes.includes(e.value) && (this.found = !0);
	}
	visitSet(e) {
		e.complement ? d(e, this.targetCharCodes) === void 0 && (this.found = !0) : d(e, this.targetCharCodes) !== void 0 && (this.found = !0);
	}
};
function m(e, t) {
	if (t instanceof RegExp) {
		let n = r(t), i = new p(e);
		return i.visit(n), i.found;
	} else {
		for (let n of t) {
			let t = n.charCodeAt(0);
			if (e.includes(t)) return !0;
		}
		return !1;
	}
}
//#endregion
export { m as canMatchCharCode, o as failedOptimizationPrefixMsg, s as getOptimizedStartCodesIndices };
