import { removeFileExtension } from './extensions.js';
import { simplifyTitle } from './title/cleanup.js';
import { parseTitleAndYear } from './title/index.js';
const websitePrefixExp = /^\[\s*[a-z]+(?:\.[a-z]+){1,4}\s*\][- ]*|^www\.[a-z]+\.(?:com|net)[ -]*/i;
const cleanReleaseGroupExp = /(-(RP|1|NZBGeek|Obfuscated|Obfuscation|Scrambled|sample|Pre|postbot|xpost|Rakuv[a-z0-9]*|WhiteRev|BUYMORE|AsRequested|AlternativeToRequested|GEROV|Z0iDS3N|Chamele0n|4P|4Planet|AlteZachen|RePACKPOST))+$/i;
const releaseGroupRegexExp = /-(?<releasegroup>[a-z0-9]+)(?<!WEB-DL|WEB-RIP|480p|720p|1080p|2160p|DTS-(HD|X|MA|ES)|([a-zA-Z]{3}-ENG))(?:\b|[-._ ])/i;
const animeReleaseGroupExp = /^\[(?<subgroup>[^\s\]\r\n](?:[^\]\r\n]{0,318}[^\s\]\r\n])?)\](?:_|-|\s|\.)?/i;
const exceptionReleaseGroupRegex = /(\[)?(?<releasegroup>(Joy|YIFY|YTS.(MX|LT|AG)|FreetheFish|VH-PROD|FTW-HS|DX-TV|Blu-bits|afm72|Anna|Bandi|Ghost|Kappa|MONOLITH|Qman|RZeroX|SAMPA|Silence|theincognito|D-Z0N3|t3nzin|Vyndros|HDO|DusIctv|DHD|SEV|CtrlHD|-ZR-|ADC|XZVN|RH|Kametsu|r00t|HONE))(\])?$/i;
const globalReleaseGroupExp = new RegExp(releaseGroupRegexExp.source, 'ig');
export function parseGroup(title, parsedTitle) {
const nowebsiteTitle = removeWebsitePrefix(title);
const releaseTitle = normalizeReleaseTitle(nowebsiteTitle, parsedTitle);
let trimmed = buildGroupCandidateTitle(nowebsiteTitle, releaseTitle);
if (trimmed.length === 0) {
return null;
}
const exceptionGroup = matchExceptionReleaseGroup(trimmed);
if (exceptionGroup !== null) {
return exceptionGroup;
}
const animeSubgroup = matchAnimeSubgroup(trimmed);
if (animeSubgroup !== null) {
return animeSubgroup;
}
trimmed = stripCleanupSuffixes(trimmed);
return matchGenericReleaseGroup(trimmed);
}
function removeWebsitePrefix(title) {
return title.replace(websitePrefixExp, '');
}
function normalizeReleaseTitle(title, parsedTitle) {
return (parsedTitle ?? parseTitleAndYear(title).title).replaceAll(' ', '.');
}
function buildGroupCandidateTitle(title, releaseTitle) {
const trimmed = title
.replaceAll(' ', '.')
.replace(releaseTitle === title ? '' : releaseTitle, '')
.replaceAll('.-.', '.');
return simplifyTitle(removeFileExtension(trimmed.trim()));
}
function matchExceptionReleaseGroup(title) {
const exceptionResult = exceptionReleaseGroupRegex.exec(title);
if (exceptionResult?.groups?.releasegroup) {
return exceptionResult.groups.releasegroup;
}
return null;
}
function matchAnimeSubgroup(title) {
const animeResult = animeReleaseGroupExp.exec(title);
return animeResult?.groups?.subgroup ?? null;
}
function stripCleanupSuffixes(title) {
return title.replace(cleanReleaseGroupExp, '');
}
function matchGenericReleaseGroup(title) {
globalReleaseGroupExp.lastIndex = 0;
for (const result of title.matchAll(globalReleaseGroupExp)) {
if (!result?.groups) {
continue;
}
const group = result.groups.releasegroup ?? '';
return group;
}
return null;
}