/**
 * Video quality from lowest to highest
 */
export enum Resolution {
	HD4k,
	HD1080,
	HD720,
	SD384,
	SD480,
	SD360,
	Unknown
}

// https://en.wikipedia.org/wiki/Pirated_movie_release_types#DVD_and_VOD_ripping
// https://en.wikipedia.org/wiki/Standard_(warez)#cite_note-txd2k9-13
/**
 * Types of releases from lowest quality to highest
 */
export enum ReleaseType {
	BluRay,
	WebDl,
	WebRip,
	WebCap,
	HDRip,
	DVDR,
	DVDRip,
	Unknown, // Unknown is better than cam tbh
	HDCAM,
	CAM
}

export enum VideoCodec {
	XviD,
	x264,
	x265,
}

export enum VideoCodecFlag {
	REMUX,
	HDR,
	HEVC
}

export enum AudioCodec {
	AC3,
	DD51,
	AAC71,
	Atmos71,
	TenBit
}

export interface ITorrentMetaInfo {
	containsOtherLanguage: boolean,
	resolution: Resolution,
	releaseType: ReleaseType,
}

/**
 * Determine meta-info from a torrent name
 */
export function parseMovieTorrentName(torrentName: string, title: string = "", year?: number) {
	// Split the meta info after the year if possible to make parsing more reliable
	let split = torrentName.split(new RegExp(`${year}|\\(${year}\\)`));
	let metaInfo = split[split.length - 1];
	title = split.length > 1 ? "" : title; // No need to check title in parsing if split correctly
	return <ITorrentMetaInfo>{
		containsOtherLanguage: determineIfContainsOtherLanguages(torrentName, title),
		resolution: determineResolution(metaInfo, title),
		releaseType: determineReleaseType(metaInfo, title),
	}
}

/**
 * Examine the torrent name for language indicators
 */
function determineIfContainsOtherLanguages(torrentName: string, title: string) {
	let matches = torrentName.match(/\b(?:Hindi|Telugu|Ita|Italian|Spanish|Latino|Russian|Arabic|Dual|Multi)\b/gi);
	for (let match of matches ?? []) {
		if (title.indexOf(match) == -1) {
			return true;
		}
	}
	return false;
}

/**
 * Interpret the resolution string as an enum value
 */
function resolutionFromString(resolution: string) {
	switch(resolution.toUpperCase()) {
		case "4K":
		case "UHD":
		case "2160":
			return Resolution.HD4k;
		case "1080":
			return Resolution.HD1080;
		case "720":
			return Resolution.HD720;
		case "480":
			return Resolution.SD480;
		case "384":
			return Resolution.SD384;
		case "360":
			return Resolution.SD360;
		default:
			return Resolution.Unknown;
	}
}

/**
 * Determine the video resolution of the torrent
 */
function determineResolution(torrentName: string, title: string) {
	let matches = torrentName.match(/\b(?:2160|1080|720|480|384|360)p?|UltraHD|UHD|4K\b/gi);
	if (matches == null) {
		return Resolution.Unknown;
	}
	let resolution = matches[matches.length - 1];

	// Make sure what was matched is not part of the title...
	if (matches.length == 1 && title.indexOf(resolution) != -1) {
		return Resolution.Unknown;
	}
	return resolutionFromString(resolution.replace(/p$/i, ""));
}

/**
 * Determine the release type of the torrent
 */
function determineReleaseType(torrentName: string, title: string) {
	let releaseTypeRegex: {[type: string]: RegExp} = {
		[ReleaseType.BluRay]: /\b(?:BR|Blu-Ray|BluRay|BDRip|BRRip|BDMV|BDR|BD25|BD50|BD5|BD9)\b/i,
		[ReleaseType.WebDl] : /\b(?:WEB.?DL|WEB-DLRip)\b/i,
		[ReleaseType.WebRip]: /\b(?:WEB.?Rip|WEB)\b/i,
		[ReleaseType.WebCap]: /\bWEB.?Cap\b/i,
		[ReleaseType.HDRip] : /\b(?:HC|HD.?Rip)\b/i,
		[ReleaseType.DVDR]  : /\bDVD.?R|DVD-Full|Full-Rip|DVD.?5|DVD.?9\b/i,
		[ReleaseType.DVDRip]: /\bDVD.?Rip|DVD.?Mux/i,
		[ReleaseType.HDCAM] : /\b(?:TRUE|HD)CAM\b/i,
		[ReleaseType.CAM]   : /\bCAM.?Rip\b/i,
	};
	let matches: RegExpMatchArray | null;
	for (let type in releaseTypeRegex) {
		matches = torrentName.match(releaseTypeRegex[type]);
		if (!matches) {
			continue;
		}
		if (matches.length == 1 || title.indexOf(matches[matches.length - 1]) == -1) {
			return <ReleaseType>parseInt(type);
		}
	}
	return ReleaseType.Unknown;
}
