import IANAZone from "../zones/IANAZone.mjs";
import FixedOffsetZone from "../zones/fixedOffsetZone.mjs";
import { isUndefined, parseFloating, parseInteger, parseMillis, signedOffset, untruncateYear } from "./util.mjs";
import { monthsShort, weekdaysLong, weekdaysShort } from "./english.mjs";

//#region ../../node_modules/.pnpm/luxon@3.5.0/node_modules/luxon/src/impl/regexParser.js
const ianaRegex = /[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;
function combineRegexes(...regexes) {
	const full = regexes.reduce((f, r) => f + r.source, "");
	return RegExp(`^${full}$`);
}
function combineExtractors(...extractors) {
	return (m) => extractors.reduce(([mergedVals, mergedZone, cursor], ex) => {
		const [val, zone, next] = ex(m, cursor);
		return [
			{
				...mergedVals,
				...val
			},
			zone || mergedZone,
			next
		];
	}, [
		{},
		null,
		1
	]).slice(0, 2);
}
function parse(s, ...patterns) {
	if (s == null) return [null, null];
	for (const [regex, extractor] of patterns) {
		const m = regex.exec(s);
		if (m) return extractor(m);
	}
	return [null, null];
}
function simpleParse(...keys) {
	return (match, cursor) => {
		const ret = {};
		let i;
		for (i = 0; i < keys.length; i++) ret[keys[i]] = parseInteger(match[cursor + i]);
		return [
			ret,
			null,
			cursor + i
		];
	};
}
const offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/;
const isoExtendedZone = `(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`;
const isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;
const isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`);
const isoTimeExtensionRegex = RegExp(`(?:T${isoTimeRegex.source})?`);
const isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/;
const isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/;
const isoOrdinalRegex = /(\d{4})-?(\d{3})/;
const extractISOWeekData = simpleParse("weekYear", "weekNumber", "weekDay");
const extractISOOrdinalData = simpleParse("year", "ordinal");
const sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/;
const sqlTimeRegex = RegExp(`${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?`);
const sqlTimeExtensionRegex = RegExp(`(?: ${sqlTimeRegex.source})?`);
function int(match, pos, fallback) {
	const m = match[pos];
	return isUndefined(m) ? fallback : parseInteger(m);
}
function extractISOYmd(match, cursor) {
	return [
		{
			year: int(match, cursor),
			month: int(match, cursor + 1, 1),
			day: int(match, cursor + 2, 1)
		},
		null,
		cursor + 3
	];
}
function extractISOTime(match, cursor) {
	return [
		{
			hours: int(match, cursor, 0),
			minutes: int(match, cursor + 1, 0),
			seconds: int(match, cursor + 2, 0),
			milliseconds: parseMillis(match[cursor + 3])
		},
		null,
		cursor + 4
	];
}
function extractISOOffset(match, cursor) {
	const local = !match[cursor] && !match[cursor + 1], fullOffset = signedOffset(match[cursor + 1], match[cursor + 2]);
	return [
		{},
		local ? null : FixedOffsetZone.instance(fullOffset),
		cursor + 3
	];
}
function extractIANAZone(match, cursor) {
	return [
		{},
		match[cursor] ? IANAZone.create(match[cursor]) : null,
		cursor + 1
	];
}
const isoTimeOnly = RegExp(`^T?${isoTimeBaseRegex.source}$`);
const isoDuration = /^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/;
function extractISODuration(match) {
	const [s, yearStr, monthStr, weekStr, dayStr, hourStr, minuteStr, secondStr, millisecondsStr] = match;
	const hasNegativePrefix = s[0] === "-";
	const negativeSeconds = secondStr && secondStr[0] === "-";
	const maybeNegate = (num, force = false) => num !== void 0 && (force || num && hasNegativePrefix) ? -num : num;
	return [{
		years: maybeNegate(parseFloating(yearStr)),
		months: maybeNegate(parseFloating(monthStr)),
		weeks: maybeNegate(parseFloating(weekStr)),
		days: maybeNegate(parseFloating(dayStr)),
		hours: maybeNegate(parseFloating(hourStr)),
		minutes: maybeNegate(parseFloating(minuteStr)),
		seconds: maybeNegate(parseFloating(secondStr), secondStr === "-0"),
		milliseconds: maybeNegate(parseMillis(millisecondsStr), negativeSeconds)
	}];
}
const obsOffsets = {
	GMT: 0,
	EDT: -240,
	EST: -300,
	CDT: -300,
	CST: -360,
	MDT: -360,
	MST: -420,
	PDT: -420,
	PST: -480
};
function fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
	const result = {
		year: yearStr.length === 2 ? untruncateYear(parseInteger(yearStr)) : parseInteger(yearStr),
		month: monthsShort.indexOf(monthStr) + 1,
		day: parseInteger(dayStr),
		hour: parseInteger(hourStr),
		minute: parseInteger(minuteStr)
	};
	if (secondStr) result.second = parseInteger(secondStr);
	if (weekdayStr) result.weekday = weekdayStr.length > 3 ? weekdaysLong.indexOf(weekdayStr) + 1 : weekdaysShort.indexOf(weekdayStr) + 1;
	return result;
}
const rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;
function extractRFC2822(match) {
	const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr, obsOffset, milOffset, offHourStr, offMinuteStr] = match, result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
	let offset;
	if (obsOffset) offset = obsOffsets[obsOffset];
	else if (milOffset) offset = 0;
	else offset = signedOffset(offHourStr, offMinuteStr);
	return [result, new FixedOffsetZone(offset)];
}
function preprocessRFC2822(s) {
	return s.replace(/\([^()]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").trim();
}
const rfc1123 = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/, rfc850 = /^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/, ascii = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;
function extractRFC1123Or850(match) {
	const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr] = match;
	return [fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr), FixedOffsetZone.utcInstance];
}
function extractASCII(match) {
	const [, weekdayStr, monthStr, dayStr, hourStr, minuteStr, secondStr, yearStr] = match;
	return [fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr), FixedOffsetZone.utcInstance];
}
const isoYmdWithTimeExtensionRegex = combineRegexes(isoYmdRegex, isoTimeExtensionRegex);
const isoWeekWithTimeExtensionRegex = combineRegexes(isoWeekRegex, isoTimeExtensionRegex);
const isoOrdinalWithTimeExtensionRegex = combineRegexes(isoOrdinalRegex, isoTimeExtensionRegex);
const isoTimeCombinedRegex = combineRegexes(isoTimeRegex);
const extractISOYmdTimeAndOffset = combineExtractors(extractISOYmd, extractISOTime, extractISOOffset, extractIANAZone);
const extractISOWeekTimeAndOffset = combineExtractors(extractISOWeekData, extractISOTime, extractISOOffset, extractIANAZone);
const extractISOOrdinalDateAndTime = combineExtractors(extractISOOrdinalData, extractISOTime, extractISOOffset, extractIANAZone);
const extractISOTimeAndOffset = combineExtractors(extractISOTime, extractISOOffset, extractIANAZone);
function parseISODate(s) {
	return parse(s, [isoYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset], [isoWeekWithTimeExtensionRegex, extractISOWeekTimeAndOffset], [isoOrdinalWithTimeExtensionRegex, extractISOOrdinalDateAndTime], [isoTimeCombinedRegex, extractISOTimeAndOffset]);
}
function parseRFC2822Date(s) {
	return parse(preprocessRFC2822(s), [rfc2822, extractRFC2822]);
}
function parseHTTPDate(s) {
	return parse(s, [rfc1123, extractRFC1123Or850], [rfc850, extractRFC1123Or850], [ascii, extractASCII]);
}
function parseISODuration(s) {
	return parse(s, [isoDuration, extractISODuration]);
}
const extractISOTimeOnly = combineExtractors(extractISOTime);
function parseISOTimeOnly(s) {
	return parse(s, [isoTimeOnly, extractISOTimeOnly]);
}
const sqlYmdWithTimeExtensionRegex = combineRegexes(sqlYmdRegex, sqlTimeExtensionRegex);
const sqlTimeCombinedRegex = combineRegexes(sqlTimeRegex);
const extractISOTimeOffsetAndIANAZone = combineExtractors(extractISOTime, extractISOOffset, extractIANAZone);
function parseSQL(s) {
	return parse(s, [sqlYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset], [sqlTimeCombinedRegex, extractISOTimeOffsetAndIANAZone]);
}

//#endregion
export { parseHTTPDate, parseISODate, parseISODuration, parseISOTimeOnly, parseRFC2822Date, parseSQL };
//# sourceMappingURL=regexParser.mjs.map