const STD = ['com', 'net', 'org', 'gov', 'edu'] as const;

const STD_MIL = [...STD, 'mil'] as const;

const ccTLD_PREFIXES: Record<string, readonly string[]> = {
	// --- Standard 5 only ---
	ar: STD,
	bd: STD,
	bg: STD,
	cn: STD_MIL,
	eg: STD,
	gr: STD,
	hk: STD,
	hr: STD,
	lk: STD,
	mx: STD_MIL,
	my: STD_MIL,
	ng: STD,
	ph: STD,
	pk: STD,
	pl: STD,
	ro: STD,
	ru: STD,
	sa: STD,
	si: STD,
	tr: STD,
	tw: STD,
	ua: STD,
	ve: STD,

	au: [...STD_MIL, 'id', 'asn', 'csiro'],
	br: [
		...STD_MIL,
		'art',
		'eco',
		'eng',
		'inf',
		'med',
		'psi',
		'tmp',
		'etc',
		'adm',
		'adv',
		'arq',
		'bio',
		'bmd',
		'cim',
		'cng',
		'cnt',
		'coop',
		'ecn',
		'esp',
		'far',
		'fm',
		'fnd',
		'fot',
		'fst',
		'g12',
		'ggf',
		'imb',
		'ind',
		'jor',
		'jus',
		'leg',
		'lel',
		'mat',
		'mp',
		'mus',
		'not',
		'ntr',
		'odo',
		'ppg',
		'pro',
		'psc',
		'qsl',
		'rec',
		'slg',
		'srv',
		'trd',
		'tur',
		'tv',
		'vet',
		'vlog',
		'wiki',
		'zlg'
	],
	id: [...STD_MIL, 'co', 'go', 'or', 'web', 'sch'],
	in: [...STD_MIL, 'co', 'gen', 'ind', 'firm', 'ernet', 'nic'],
	kr: [...STD_MIL, 'co', 'go', 'or', 'ac', 're'],
	nz: [
		...STD_MIL,
		'co',
		'gen',
		'geek',
		'kiwi',
		'maori',
		'school',
		'govt',
		'health',
		'iwi',
		'parliament'
	],
	sg: [...STD, 'per'],
	th: ['co', 'go', 'or', 'in', 'ac', 'mi', 'net'],

	ae: ['co', 'net', 'org', 'gov', 'ac', 'sch'],
	hu: ['co', 'net', 'org', 'gov', 'edu'],
	il: ['co', 'net', 'org', 'gov', 'ac', 'muni'],
	jp: ['ac', 'ad', 'co', 'ed', 'go', 'gr', 'lg', 'ne', 'or'],
	ke: ['co', 'or', 'ne', 'go', 'ac', 'sc'],
	rs: ['co', 'net', 'org', 'gov', 'edu'],
	uk: ['co', 'org', 'net', 'ac', 'gov', 'mil', 'nhs', 'police', 'mod', 'ltd', 'plc', 'me', 'sch'],
	za: ['co', 'org', 'net', 'web', 'law', 'mil']
};

const WILDCARD_BASES: Record<string, readonly string[]> = {
	br: ['nom', 'blog'],
	jp: [
		'kobe',
		'kyoto',
		'nagoya',
		'osaka',
		'sapporo',
		'sendai',
		'tokyo',
		'yokohama',
		'aichi',
		'akita',
		'aomori',
		'chiba',
		'ehime',
		'fukui',
		'fukuoka',
		'fukushima',
		'gifu',
		'gunma',
		'hiroshima',
		'hokkaido',
		'hyogo',
		'ibaraki',
		'ishikawa',
		'iwate',
		'kagawa',
		'kagoshima',
		'kanagawa',
		'kochi',
		'kumamoto',
		'mie',
		'miyagi',
		'miyazaki',
		'nagano',
		'nara',
		'niigata',
		'oita',
		'okayama',
		'okinawa',
		'saga',
		'saitama',
		'shiga',
		'shimane',
		'shizuoka',
		'tochigi',
		'tokushima',
		'tottori',
		'toyama',
		'wakayama',
		'yamagata',
		'yamaguchi',
		'yamanashi'
	]
};

function buildSuffixSet(suffixes: Record<string, readonly string[]>): Set<string> {
	const set = new Set<string>();

	for (const [tld, parts] of Object.entries(suffixes)) {
		for (const part of parts) {
			set.add(`${part}.${tld}`);
		}
	}

	return set;
}

export const TWO_PART_PUBLIC_SUFFIXES = buildSuffixSet(ccTLD_PREFIXES);
export const WILDCARD_PUBLIC_SUFFIXES = buildSuffixSet(WILDCARD_BASES);

// Matches one or more trailing "/" characters at the end of a URL/path.
export const TRAILING_SLASHES_REGEX = /\/+$/;
