import { ccount } from "../../ccount/index.js";
import { ok } from "../../devlop/lib/default.js";
import { unicodePunctuation, unicodeWhitespace } from "../../micromark-util-character/index.js";
import { findAndReplace } from "../../mdast-util-find-and-replace/lib/index.js";
var inConstruct = "phrasing", notInConstruct = [
	"autolink",
	"link",
	"image",
	"label"
];
function gfmAutolinkLiteralFromMarkdown() {
	return {
		transforms: [transformGfmAutolinkLiterals],
		enter: {
			literalAutolink: enterLiteralAutolink,
			literalAutolinkEmail: enterLiteralAutolinkValue,
			literalAutolinkHttp: enterLiteralAutolinkValue,
			literalAutolinkWww: enterLiteralAutolinkValue
		},
		exit: {
			literalAutolink: exitLiteralAutolink,
			literalAutolinkEmail: exitLiteralAutolinkEmail,
			literalAutolinkHttp: exitLiteralAutolinkHttp,
			literalAutolinkWww: exitLiteralAutolinkWww
		}
	};
}
function gfmAutolinkLiteralToMarkdown() {
	return { unsafe: [
		{
			character: "@",
			before: "[+\\-.\\w]",
			after: "[\\-.\\w]",
			inConstruct,
			notInConstruct
		},
		{
			character: ".",
			before: "[Ww]",
			after: "[\\-.\\w]",
			inConstruct,
			notInConstruct
		},
		{
			character: ":",
			before: "[ps]",
			after: "\\/",
			inConstruct,
			notInConstruct
		}
	] };
}
function enterLiteralAutolink(t) {
	this.enter({
		type: "link",
		title: null,
		url: "",
		children: []
	}, t);
}
function enterLiteralAutolinkValue(t) {
	this.config.enter.autolinkProtocol.call(this, t);
}
function exitLiteralAutolinkHttp(t) {
	this.config.exit.autolinkProtocol.call(this, t);
}
function exitLiteralAutolinkWww(t) {
	this.config.exit.data.call(this, t);
	let m = this.stack[this.stack.length - 1];
	m.type, m.url = "http://" + this.sliceSerialize(t);
}
function exitLiteralAutolinkEmail(t) {
	this.config.exit.autolinkEmail.call(this, t);
}
function exitLiteralAutolink(t) {
	this.exit(t);
}
function transformGfmAutolinkLiterals(t) {
	findAndReplace(t, [[/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], [RegExp("(?<=^|\\s|\\p{P}|\\p{S})([-.\\w+]+)@([-\\w]+(?:\\.[-\\w]+)+)", "gu"), findEmail]], { ignore: ["link", "linkReference"] });
}
function findUrl(t, m, h, g, _) {
	let v = "";
	if (!previous(_) || (/^w/i.test(m) && (h = m + h, m = "", v = "http://"), !isCorrectDomain(h))) return !1;
	let y = splitUrl(h + g);
	if (!y[0]) return !1;
	let b = {
		type: "link",
		title: null,
		url: v + m + y[0],
		children: [{
			type: "text",
			value: m + y[0]
		}]
	};
	return y[1] ? [b, {
		type: "text",
		value: y[1]
	}] : b;
}
function findEmail(t, m, h, g) {
	return !previous(g, !0) || /[-\d_]$/.test(h) ? !1 : {
		type: "link",
		title: null,
		url: "mailto:" + m + "@" + h,
		children: [{
			type: "text",
			value: m + "@" + h
		}]
	};
}
function isCorrectDomain(t) {
	let m = t.split(".");
	return !(m.length < 2 || m[m.length - 1] && (/_/.test(m[m.length - 1]) || !/[a-zA-Z\d]/.test(m[m.length - 1])) || m[m.length - 2] && (/_/.test(m[m.length - 2]) || !/[a-zA-Z\d]/.test(m[m.length - 2])));
}
function splitUrl(m) {
	let h = /[!"&'),.:;<>?\]}]+$/.exec(m);
	if (!h) return [m, void 0];
	m = m.slice(0, h.index);
	let g = h[0], _ = g.indexOf(")"), v = ccount(m, "("), y = ccount(m, ")");
	for (; _ !== -1 && v > y;) m += g.slice(0, _ + 1), g = g.slice(_ + 1), _ = g.indexOf(")"), y++;
	return [m, g];
}
function previous(t, m) {
	let _ = t.input.charCodeAt(t.index - 1);
	return (t.index === 0 || unicodeWhitespace(_) || unicodePunctuation(_)) && (!m || _ !== 47);
}
export { gfmAutolinkLiteralFromMarkdown, gfmAutolinkLiteralToMarkdown };
