import { markdownLineEndingOrSpace } from "../../micromark-util-character/index.js";
import { normalizeIdentifier } from "../../micromark-util-normalize-identifier/index.js";
import { push, splice } from "../../micromark-util-chunked/index.js";
import { resolveAll } from "../../micromark-util-resolve-all/index.js";
import { factoryDestination } from "../../micromark-factory-destination/index.js";
import { factoryLabel } from "../../micromark-factory-label/index.js";
import { factoryTitle } from "../../micromark-factory-title/index.js";
import { factoryWhitespace } from "../../micromark-factory-whitespace/index.js";
const labelEnd = {
	name: "labelEnd",
	resolveAll: resolveAllLabelEnd,
	resolveTo: resolveToLabelEnd,
	tokenize: tokenizeLabelEnd
};
var resourceConstruct = { tokenize: tokenizeResource }, referenceFullConstruct = { tokenize: tokenizeReferenceFull }, referenceCollapsedConstruct = { tokenize: tokenizeReferenceCollapsed };
function resolveAllLabelEnd(e) {
	let i = -1, a = [];
	for (; ++i < e.length;) {
		let o = e[i][1];
		if (a.push(e[i]), o.type === "labelImage" || o.type === "labelLink" || o.type === "labelEnd") {
			let e = o.type === "labelImage" ? 4 : 2;
			o.type = "data", i += e;
		}
	}
	return e.length !== a.length && splice(e, 0, e.length, a), e;
}
function resolveToLabelEnd(e, i) {
	let c = e.length, l = 0, u, d, f, p;
	for (; c--;) if (u = e[c][1], d) {
		if (u.type === "link" || u.type === "labelLink" && u._inactive) break;
		e[c][0] === "enter" && u.type === "labelLink" && (u._inactive = !0);
	} else if (f) {
		if (e[c][0] === "enter" && (u.type === "labelImage" || u.type === "labelLink") && !u._balanced && (d = c, u.type !== "labelLink")) {
			l = 2;
			break;
		}
	} else u.type === "labelEnd" && (f = c);
	let m = {
		type: e[d][1].type === "labelLink" ? "link" : "image",
		start: { ...e[d][1].start },
		end: { ...e[e.length - 1][1].end }
	}, h = {
		type: "label",
		start: { ...e[d][1].start },
		end: { ...e[f][1].end }
	}, g = {
		type: "labelText",
		start: { ...e[d + l + 2][1].end },
		end: { ...e[f - 2][1].start }
	};
	return p = [[
		"enter",
		m,
		i
	], [
		"enter",
		h,
		i
	]], p = push(p, e.slice(d + 1, d + l + 3)), p = push(p, [[
		"enter",
		g,
		i
	]]), p = push(p, resolveAll(i.parser.constructs.insideSpan.null, e.slice(d + l + 4, f - 3), i)), p = push(p, [
		[
			"exit",
			g,
			i
		],
		e[f - 2],
		e[f - 1],
		[
			"exit",
			h,
			i
		]
	]), p = push(p, e.slice(f + 1)), p = push(p, [[
		"exit",
		m,
		i
	]]), splice(e, d, e.length, p), e;
}
function tokenizeLabelEnd(e, a, o) {
	let s = this, c = s.events.length, l, u;
	for (; c--;) if ((s.events[c][1].type === "labelImage" || s.events[c][1].type === "labelLink") && !s.events[c][1]._balanced) {
		l = s.events[c][1];
		break;
	}
	return d;
	function d(a) {
		return l ? l._inactive ? v(a) : (u = s.parser.defined.includes(normalizeIdentifier(s.sliceSerialize({
			start: l.end,
			end: s.now()
		}))), e.enter("labelEnd"), e.enter("labelMarker"), e.consume(a), e.exit("labelMarker"), e.exit("labelEnd"), f) : o(a);
	}
	function f(i) {
		return i === 40 ? e.attempt(resourceConstruct, _, u ? _ : v)(i) : i === 91 ? e.attempt(referenceFullConstruct, _, u ? g : v)(i) : u ? _(i) : v(i);
	}
	function g(i) {
		return e.attempt(referenceCollapsedConstruct, _, v)(i);
	}
	function _(e) {
		return a(e);
	}
	function v(e) {
		return l._balanced = !0, o(e);
	}
}
function tokenizeResource(i, a, o) {
	return s;
	function s(e) {
		return i.enter("resource"), i.enter("resourceMarker"), i.consume(e), i.exit("resourceMarker"), l;
	}
	function l(a) {
		return markdownLineEndingOrSpace(a) ? factoryWhitespace(i, f)(a) : f(a);
	}
	function f(e) {
		return e === 41 ? _(e) : factoryDestination(i, p, m, "resourceDestination", "resourceDestinationLiteral", "resourceDestinationLiteralMarker", "resourceDestinationRaw", "resourceDestinationString", 32)(e);
	}
	function p(a) {
		return markdownLineEndingOrSpace(a) ? factoryWhitespace(i, h)(a) : _(a);
	}
	function m(e) {
		return o(e);
	}
	function h(e) {
		return e === 34 || e === 39 || e === 40 ? factoryTitle(i, g, o, "resourceTitle", "resourceTitleMarker", "resourceTitleString")(e) : _(e);
	}
	function g(a) {
		return markdownLineEndingOrSpace(a) ? factoryWhitespace(i, _)(a) : _(a);
	}
	function _(e) {
		return e === 41 ? (i.enter("resourceMarker"), i.consume(e), i.exit("resourceMarker"), i.exit("resource"), a) : o(e);
	}
}
function tokenizeReferenceFull(e, a, o) {
	let s = this;
	return c;
	function c(i) {
		return factoryLabel.call(s, e, u, d, "reference", "referenceMarker", "referenceString")(i);
	}
	function u(e) {
		return s.parser.defined.includes(normalizeIdentifier(s.sliceSerialize(s.events[s.events.length - 1][1]).slice(1, -1))) ? a(e) : o(e);
	}
	function d(e) {
		return o(e);
	}
}
function tokenizeReferenceCollapsed(e, i, a) {
	return o;
	function o(i) {
		return e.enter("reference"), e.enter("referenceMarker"), e.consume(i), e.exit("referenceMarker"), s;
	}
	function s(o) {
		return o === 93 ? (e.enter("referenceMarker"), e.consume(o), e.exit("referenceMarker"), e.exit("reference"), i) : a(o);
	}
}
export { labelEnd };
