import { ftlToJSON, JSONToFtl } from 'ftl-tx';
import fs from 'fs-extra';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import { ftlFileBaseNames as sourceFileBaseNames } from './config.js';
import { onError, onProgress, onSuccess } from './utils.js';

const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const localesDir = join(ROOT, 'chrome', 'locale');
const TRANSIFEX_FILE_NAME = 'zotero.json';

function getLocaleDir(locale) {
	return join(localesDir, locale, 'zotero');
}

async function getFTL() {
	const t1 = performance.now();
	
	const foundLocales = (await fs.readdir(localesDir, { withFileTypes: true }))
		.filter(dirent => dirent.isDirectory())
		.map(dirent => dirent.name)
		// Valid locale codes only
		.filter(name => /^[a-z]{2}(-[A-Z]{2})?$/.test(name));
	
	let count = 0;
	for (let locale of foundLocales) {
		// Skip source locale
		if (locale == 'en-US') {
			continue;
		}

		const jsonFilePath = join(getLocaleDir(locale), TRANSIFEX_FILE_NAME);
		let jsonFromTransifex = {};
		try {
			const json = await fs.readJSON(jsonFilePath);
			jsonFromTransifex = json;
		}
		catch (e) {
			// no .json file from transifex
		}

		for (let sourceFileBaseName of sourceFileBaseNames) {
			const ftlFilePath = join(getLocaleDir(locale), sourceFileBaseName + '.ftl');
			let jsonFromLocalFTL = {};
			try {
				const ftl = await fs.readFile(ftlFilePath, 'utf8');
				jsonFromLocalFTL = ftlToJSON(ftl);
			}
			catch (e) {
				// no local .ftl file
			}
			let baseFTL;
			let jsonFromEnUSFTL = {};

			try {
				const enUSFtlPath = join(getLocaleDir('en-US'), sourceFileBaseName + '.ftl');
				baseFTL = await fs.readFile(enUSFtlPath, 'utf8');
				jsonFromEnUSFTL = ftlToJSON(baseFTL);
			}
			catch (e) {
				throw new Error(`No en-US .ftl file for ${sourceFileBaseName}.ftl`);
			}

			const mergedSourceJSON = { ...jsonFromEnUSFTL, ...jsonFromLocalFTL };
			const sourceKeys = Object.keys(mergedSourceJSON);
			const translated = new Map();

			for (let key of sourceKeys) {
				//  ignore empty messages from transifex
				if (key in jsonFromTransifex && jsonFromTransifex[key]?.string) {
					translated.set(key, jsonFromTransifex[key]);
				}
				else {
					translated.set(key, mergedSourceJSON[key]);
				}
			}

			try {
				const ftl = JSONToFtl(Object.fromEntries(translated), baseFTL);
				const outFtlPath = join(getLocaleDir(locale), sourceFileBaseName + '.ftl');
				await fs.outputFile(outFtlPath, ftl);
				onProgress(`${locale}/${sourceFileBaseName}.ftl`, null, 'localize');
				count++;
			}
			catch (e) {
				e.message = `Failed to localize "${locale}": ${e.message}`;
				throw e;
			}
		}
	}
	
	const t2 = performance.now();
	return ({
		action: 'localize',
		count,
		totalCount: count,
		processingTime: t2 - t1
	});
}


if (process.argv[1] === fileURLToPath(import.meta.url)) {
	(async () => {
		try {
			onSuccess(await getFTL());
		}
		catch (err) {
			process.exitCode = 1;
			global.isError = true;
			onError(err);
		}
	})();
}