import { markdownLineEndingOrSpace } from "../../micromark-util-character/index.js";
import { normalizeIdentifier } from "../../micromark-util-normalize-identifier/index.js";
import { factorySpace } from "../../micromark-factory-space/index.js";
import { blankLine } from "../../micromark-core-commonmark/lib/blank-line.js";
var indent = {
	tokenize: tokenizeIndent,
	partial: !0
};
function gfmFootnote() {
	return {
		document: { 91: {
			name: "gfmFootnoteDefinition",
			tokenize: tokenizeDefinitionStart,
			continuation: { tokenize: tokenizeDefinitionContinuation },
			exit: gfmFootnoteDefinitionEnd
		} },
		text: {
			91: {
				name: "gfmFootnoteCall",
				tokenize: tokenizeGfmFootnoteCall
			},
			93: {
				name: "gfmPotentialFootnoteCall",
				add: "after",
				tokenize: tokenizePotentialGfmFootnoteCall,
				resolveTo: resolveToPotentialGfmFootnoteCall
			}
		}
	};
}
function tokenizePotentialGfmFootnoteCall(e, n, r) {
	let i = this, a = i.events.length, o = i.parser.gfmFootnotes || (i.parser.gfmFootnotes = []), s;
	for (; a--;) {
		let e = i.events[a][1];
		if (e.type === "labelImage") {
			s = e;
			break;
		}
		if (e.type === "gfmFootnoteCall" || e.type === "labelLink" || e.type === "label" || e.type === "image" || e.type === "link") break;
	}
	return c;
	function c(a) {
		if (!s || !s._balanced) return r(a);
		let c = normalizeIdentifier(i.sliceSerialize({
			start: s.end,
			end: i.now()
		}));
		return c.codePointAt(0) !== 94 || !o.includes(c.slice(1)) ? r(a) : (e.enter("gfmFootnoteCallLabelMarker"), e.consume(a), e.exit("gfmFootnoteCallLabelMarker"), n(a));
	}
}
function resolveToPotentialGfmFootnoteCall(e, t) {
	let n = e.length;
	for (; n--;) if (e[n][1].type === "labelImage" && e[n][0] === "enter") {
		e[n][1];
		break;
	}
	e[n + 1][1].type = "data", e[n + 3][1].type = "gfmFootnoteCallLabelMarker";
	let r = {
		type: "gfmFootnoteCall",
		start: Object.assign({}, e[n + 3][1].start),
		end: Object.assign({}, e[e.length - 1][1].end)
	}, i = {
		type: "gfmFootnoteCallMarker",
		start: Object.assign({}, e[n + 3][1].end),
		end: Object.assign({}, e[n + 3][1].end)
	};
	i.end.column++, i.end.offset++, i.end._bufferIndex++;
	let a = {
		type: "gfmFootnoteCallString",
		start: Object.assign({}, i.end),
		end: Object.assign({}, e[e.length - 1][1].start)
	}, o = {
		type: "chunkString",
		contentType: "string",
		start: Object.assign({}, a.start),
		end: Object.assign({}, a.end)
	}, s = [
		e[n + 1],
		e[n + 2],
		[
			"enter",
			r,
			t
		],
		e[n + 3],
		e[n + 4],
		[
			"enter",
			i,
			t
		],
		[
			"exit",
			i,
			t
		],
		[
			"enter",
			a,
			t
		],
		[
			"enter",
			o,
			t
		],
		[
			"exit",
			o,
			t
		],
		[
			"exit",
			a,
			t
		],
		e[e.length - 2],
		e[e.length - 1],
		[
			"exit",
			r,
			t
		]
	];
	return e.splice(n, e.length - n + 1, ...s), e;
}
function tokenizeGfmFootnoteCall(n, r, i) {
	let a = this, o = a.parser.gfmFootnotes || (a.parser.gfmFootnotes = []), s = 0, c;
	return l;
	function l(e) {
		return n.enter("gfmFootnoteCall"), n.enter("gfmFootnoteCallLabelMarker"), n.consume(e), n.exit("gfmFootnoteCallLabelMarker"), u;
	}
	function u(e) {
		return e === 94 ? (n.enter("gfmFootnoteCallMarker"), n.consume(e), n.exit("gfmFootnoteCallMarker"), n.enter("gfmFootnoteCallString"), n.enter("chunkString").contentType = "string", d) : i(e);
	}
	function d(l) {
		if (s > 999 || l === 93 && !c || l === null || l === 91 || markdownLineEndingOrSpace(l)) return i(l);
		if (l === 93) {
			n.exit("chunkString");
			let e = n.exit("gfmFootnoteCallString");
			return o.includes(normalizeIdentifier(a.sliceSerialize(e))) ? (n.enter("gfmFootnoteCallLabelMarker"), n.consume(l), n.exit("gfmFootnoteCallLabelMarker"), n.exit("gfmFootnoteCall"), r) : i(l);
		}
		return markdownLineEndingOrSpace(l) || (c = !0), s++, n.consume(l), l === 92 ? f : d;
	}
	function f(e) {
		return e === 91 || e === 92 || e === 93 ? (n.consume(e), s++, d) : d(e);
	}
}
function tokenizeDefinitionStart(r, i, a) {
	let o = this, s = o.parser.gfmFootnotes || (o.parser.gfmFootnotes = []), c, l = 0, u;
	return d;
	function d(e) {
		return r.enter("gfmFootnoteDefinition")._container = !0, r.enter("gfmFootnoteDefinitionLabel"), r.enter("gfmFootnoteDefinitionLabelMarker"), r.consume(e), r.exit("gfmFootnoteDefinitionLabelMarker"), f;
	}
	function f(e) {
		return e === 94 ? (r.enter("gfmFootnoteDefinitionMarker"), r.consume(e), r.exit("gfmFootnoteDefinitionMarker"), r.enter("gfmFootnoteDefinitionLabelString"), r.enter("chunkString").contentType = "string", p) : a(e);
	}
	function p(n) {
		if (l > 999 || n === 93 && !u || n === null || n === 91 || markdownLineEndingOrSpace(n)) return a(n);
		if (n === 93) {
			r.exit("chunkString");
			let e = r.exit("gfmFootnoteDefinitionLabelString");
			return c = normalizeIdentifier(o.sliceSerialize(e)), r.enter("gfmFootnoteDefinitionLabelMarker"), r.consume(n), r.exit("gfmFootnoteDefinitionLabelMarker"), r.exit("gfmFootnoteDefinitionLabel"), h;
		}
		return markdownLineEndingOrSpace(n) || (u = !0), l++, r.consume(n), n === 92 ? m : p;
	}
	function m(e) {
		return e === 91 || e === 92 || e === 93 ? (r.consume(e), l++, p) : p(e);
	}
	function h(e) {
		return e === 58 ? (r.enter("definitionMarker"), r.consume(e), r.exit("definitionMarker"), s.includes(c) || s.push(c), factorySpace(r, g, "gfmFootnoteDefinitionWhitespace")) : a(e);
	}
	function g(e) {
		return i(e);
	}
}
function tokenizeDefinitionContinuation(e, t, n) {
	return e.check(blankLine, t, e.attempt(indent, t, n));
}
function gfmFootnoteDefinitionEnd(e) {
	e.exit("gfmFootnoteDefinition");
}
function tokenizeIndent(e, t, r) {
	let i = this;
	return factorySpace(e, a, "gfmFootnoteDefinitionIndent", 5);
	function a(e) {
		let n = i.events[i.events.length - 1];
		return n && n[1].type === "gfmFootnoteDefinitionIndent" && n[2].sliceSerialize(n[1], !0).length === 4 ? t(e) : r(e);
	}
}
export { gfmFootnote };
