import { execCommand, isMac } from '../tool-utils';
import { existsSync, readFile } from 'fs-extra';
const gettextParser = require('gettext-parser');

export interface TranslationStatus {
	locale?: string;
	languageName?: string;
	translatorName: string;
	percentDone: number;
	untranslatedCount: number;
	pluralForms?: string;
}

export type Translations = Record<string, string[]>;

export const removePoHeaderDate = async (filePath: string) => {
	let sedPrefix = 'sed -i';
	if (isMac()) sedPrefix += ' ""'; // Note: on macOS it has to be 'sed -i ""' (BSD quirk)
	await execCommand(`${sedPrefix} -e'/POT-Creation-Date:/d' "${filePath}"`);
	await execCommand(`${sedPrefix} -e'/PO-Revision-Date:/d' "${filePath}"`);
};

export const translationExecutablePath = (file: string) => {
	const potentialPaths = [
		'/usr/local/opt/gettext/bin/',
		'/opt/local/bin/',
		'/usr/local/bin/',
		'/opt/homebrew/bin/',
	];

	for (const path of potentialPaths) {
		const pathFile = path + file;
		if (existsSync(pathFile)) {
			return pathFile;
		}
	}

	throw new Error(`${file} could not be found. Please install via brew or MacPorts.\n`);
};

export const mergePotToPo = async (potFilePath: string, poFilePath: string) => {
	let msgmergePath = 'msgmerge';
	if (isMac()) msgmergePath = translationExecutablePath('msgmerge'); // Needs to have been installed with `brew install gettext`

	const command = `${msgmergePath} -U "${poFilePath}" "${potFilePath}"`;
	const result = await execCommand(command);
	if (result && result.trim()) console.info(result.trim());
	await removePoHeaderDate(poFilePath);
};

export const parsePoFile = async (filePath: string) => {
	const content = await readFile(filePath);
	return gettextParser.po.parse(content);
};

// Convert the gettext translations, as returned by `gettextParser.po.parse()`
// to a <string, string> map, with the English text on the left and the
// translation on the right. If a particular translation is missing, no entry
// will be returned. The caller should display the English text in this case.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export const parseTranslations = (gettextTranslations: any) => {
	const output: Translations = {};

	// Translations are grouped by "msgctxt"

	for (const msgctxt of Object.keys(gettextTranslations.translations)) {
		const translations = gettextTranslations.translations[msgctxt];

		for (const n in translations) {
			if (!translations.hasOwnProperty(n)) continue;
			if (n === '') continue;
			const t = translations[n];
			let translated: string[] = [];
			if (t.comments && t.comments.flag && t.comments.flag.indexOf('fuzzy') >= 0) {
				// Don't include fuzzy translations
			} else {
				translated = t['msgstr'];
			}

			if (translated.length) output[n] = translated;
		}
	}

	return output;
};
