import head_default from "../../../../lodash-es/head.js";
import map_default from "../../../../lodash-es/map.js";
import reduce_default from "../../../../lodash-es/reduce.js";
import { NonTerminal, Rule, Terminal } from "../../../../@chevrotain/gast/lib/src/model.js";
import { getProductionDslName } from "../../../../@chevrotain/gast/lib/src/helpers.js";
import { hasTokenLabel, tokenLabel } from "../scan/tokens_public.js";
const defaultParserErrorProvider = {
	buildMismatchTokenMessage({ expected: e, actual: t, previous: n, ruleName: r }) {
		return `Expecting ${hasTokenLabel(e) ? `--> ${tokenLabel(e)} <--` : `token of type --> ${e.name} <--`} but found --> '${t.image}' <--`;
	},
	buildNotAllInputParsedMessage({ firstRedundant: e, ruleName: t }) {
		return "Redundant input, expecting EOF but found: " + e.image;
	},
	buildNoViableAltMessage({ expectedPathsPerAlt: r, actual: i, previous: a, customUserDescription: o, ruleName: s }) {
		let l = "\nbut found: '" + head_default(i).image + "'";
		return o ? "Expecting: " + o + l : `Expecting: one of these possible Token sequences:\n${map_default(map_default(reduce_default(r, (e, t) => e.concat(t), []), (e) => `[${map_default(e, (e) => tokenLabel(e)).join(", ")}]`), (e, t) => `  ${t + 1}. ${e}`).join("\n")}` + l;
	},
	buildEarlyExitMessage({ expectedIterationPaths: n, actual: r, customUserDescription: i, ruleName: a }) {
		let o = "\nbut found: '" + head_default(r).image + "'";
		return i ? "Expecting: " + i + o : `Expecting: expecting at least one iteration which starts with one of these possible Token sequences::\n  <${map_default(n, (e) => `[${map_default(e, (e) => tokenLabel(e)).join(",")}]`).join(" ,")}>` + o;
	}
};
Object.freeze(defaultParserErrorProvider);
const defaultGrammarResolverErrorProvider = { buildRuleNotFoundError(e, t) {
	return "Invalid grammar, reference to a rule which is not defined: ->" + t.nonTerminalName + "<-\ninside top level rule: ->" + e.name + "<-";
} }, defaultGrammarValidatorErrorProvider = {
	buildDuplicateFoundError(t, n) {
		function i(e) {
			return e instanceof Terminal ? e.terminalType.name : e instanceof NonTerminal ? e.nonTerminalName : "";
		}
		let s = t.name, c = head_default(n), l = c.idx, u = getProductionDslName(c), d = i(c), f = `->${u}${l > 0 ? l : ""}<- ${d ? `with argument: ->${d}<-` : ""}
                  appears more than once (${n.length} times) in the top level rule: ->${s}<-.                  
                  For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES 
                  `;
		return f = f.replace(/[ \t]+/g, " "), f = f.replace(/\s\s+/g, "\n"), f;
	},
	buildNamespaceConflictError(e) {
		return `Namespace conflict found in grammar.\nThe grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${e.name}>.\nTo resolve this make sure each Terminal and Non-Terminal names are unique\nThis is easy to accomplish by using the convention that Terminal names start with an uppercase letter\nand Non-Terminal names start with a lower case letter.`;
	},
	buildAlternationPrefixAmbiguityError(e) {
		let n = map_default(e.prefixPath, (e) => tokenLabel(e)).join(", "), r = e.alternation.idx === 0 ? "" : e.alternation.idx;
		return `Ambiguous alternatives: <${e.ambiguityIndices.join(" ,")}> due to common lookahead prefix\nin <OR${r}> inside <${e.topLevelRule.name}> Rule,\n<${n}> may appears as a prefix path in all these alternatives.\nSee: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX\nFor Further details.`;
	},
	buildAlternationAmbiguityError(e) {
		let n = e.alternation.idx === 0 ? "" : e.alternation.idx, r = e.prefixPath.length === 0, i = `Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(" ,")}> in <OR${n}> inside <${e.topLevelRule.name}> Rule,\n`;
		if (r) i += "These alternatives are all empty (match no tokens), making them indistinguishable.\nOnly the last alternative may be empty.\n";
		else {
			let n = map_default(e.prefixPath, (e) => tokenLabel(e)).join(", ");
			i += `<${n}> may appears as a prefix path in all these alternatives.\n`;
		}
		return i += "See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.", i;
	},
	buildEmptyRepetitionError(e) {
		let t = getProductionDslName(e.repetition);
		return e.repetition.idx !== 0 && (t += e.repetition.idx), `The repetition <${t}> within Rule <${e.topLevelRule.name}> can never consume any tokens.\nThis could lead to an infinite loop.`;
	},
	buildTokenNameError(e) {
		/* istanbul ignore next */
		return "deprecated";
	},
	buildEmptyAlternationError(e) {
		return `Ambiguous empty alternative: <${e.emptyChoiceIdx + 1}> in <OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\nOnly the last alternative may be an empty alternative.`;
	},
	buildTooManyAlternativesError(e) {
		return `An Alternation cannot have more than 256 alternatives:\n<OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\n has ${e.alternation.definition.length + 1} alternatives.`;
	},
	buildLeftRecursionError(e) {
		let n = e.topLevelRule.name;
		return `Left Recursion found in grammar.\nrule: <${n}> can be invoked from itself (directly or indirectly)\nwithout consuming any Tokens. The grammar path that causes this is: \n ${`${n} --> ${map_default(e.leftRecursionPath, (e) => e.name).concat([n]).join(" --> ")}`}\n To fix this refactor your grammar to remove the left recursion.\nsee: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`;
	},
	buildInvalidRuleNameError(e) {
		/* istanbul ignore next */
		return "deprecated";
	},
	buildDuplicateRuleNameError(e) {
		let t;
		return t = e.topLevelRule instanceof Rule ? e.topLevelRule.name : e.topLevelRule, `Duplicate definition, rule: ->${t}<- is already defined in the grammar: ->${e.grammarName}<-`;
	}
};
export { defaultGrammarResolverErrorProvider, defaultGrammarValidatorErrorProvider, defaultParserErrorProvider };
