import gt from "gettext-parser";
import fs from "node:fs/promises";
import path from "node:path";
import util from "node:util";
import { execFile as execFileCb } from "node:child_process";

const execFile = util.promisify(execFileCb);

async function processMsgId(msgId) {
  return execFile("grep", ["-r", "-o", msgId, "./src"]).catch(() => {
    return msgId;
  });
}

async function processFile(f) {
  const content = await fs.readFile(f);
  const data = gt.po.parse(content, "utf-8");
  const translations = data.translations[""];
  const badIds = [];

  for (const property in translations) {
    const data = await processMsgId(translations[property].msgid);
    if (data != null && data.stdout === undefined) {
      badIds.push(data);
    }
  }

  return badIds;
}

async function cleanFile(f, badIds) {
  console.log("\n\nDoing automatic cleanup");

  const content = await fs.readFile(f);
  const data = gt.po.parse(content, "utf-8");
  const translations = data.translations[""];
  const keys = Object.keys(translations);

  for (const key of keys) {
    property = translations[key];
    if (badIds.includes(property.msgid)) {
      console.log("----> deleting", property.msgid);
      delete data.translations[""][key];
    }
  }

  const buff = gt.po.compile(data, { sort: true });
  await fs.writeFile(f, buff);
}

async function findExecutionTimeTranslations() {
  const { stdout } = await execFile("grep", [
    "-r",
    "-h",
    "-F",
    "(tr (",
    "./src",
  ]);
  console.log(stdout);
}

async function welcome() {
  console.log(
    "####################################################################",
  );
  console.log(
    "#                UNUSED TRANSLATIONS FINDER                        #",
  );
  console.log(
    "####################################################################",
  );
  console.log("\n");
  console.log(
    "DISCLAIMER: Some translations are only available at execution time.",
  );
  console.log("            This finder can't process them, so there can be");
  console.log("            false positives.\n");
  console.log("            If you want to do an automatic clean anyway,");
  console.log("            call the script with:");
  console.log("            npm run find-unused-translations -- --clean");
  console.log("            For example:");
  console.log(
    "--------------------------------------------------------------------",
  );
  await findExecutionTimeTranslations();
  console.log(
    "--------------------------------------------------------------------",
  );
}

const doCleanup = process.argv.slice(2)[0] == "--clean";

(async () => {
  await welcome();
  const target = path.normalize("./translations/en.po");
  const badIds = await processFile(target);

  if (doCleanup) {
    cleanFile(target, badIds);
  } else {
    for (const badId of badIds) {
      console.log(badId);
    }
  }
})();