// The toml looks like that:
// # The translation are partially generated by copilot

// [description]
// en = "An integrated language service for Typst"
// zh-CN = "Typst 的集成语言服务"

import * as fs from "fs/promises";
import * as path from "path";

const projectRoot = path.resolve(import.meta.dirname, "..");

/**
 *
 * @param {string} output
 * @param {string[]} inputs
 * @returns
 */
async function translate(output, kind, inputs) {
  const lines = (
    await Promise.all(
      inputs.map(async (input) =>
        (await fs.readFile(path.resolve(projectRoot, input), "utf-8"))
          .split("\n")
          .map((line) => line.trim())
          .filter((line) => !line.startsWith("#") && line.length > 0),
      ),
    )
  ).flat();

  const translations = {};
  let key = "";
  for (let line of lines) {
    if (line.startsWith("[")) {
      key = line.substring(1, line.length - 1);
      if (key.startsWith('"')) {
        key = JSON.parse(key);
      }
    } else {
      const equalIndex = line.indexOf("=");
      const lang = line.substring(0, equalIndex).trim();
      const value = line.substring(equalIndex + 1).trim();

      translations[lang] ||= {};
      translations[lang][key] = JSON.parse(value);
    }
  }

  const langs = Object.keys(translations);
  const langEn = langs.find((lang) => lang === "en");
  if (!langEn) {
    console.error("en is required");
    return;
  }

  const langRest = langs.filter((lang) => lang !== "en");

  const langDir = path.resolve(projectRoot, output);
  await fs.mkdir(langDir, { recursive: true });

  const langEnPath = `${langDir}/${kind}.json`;
  const langEnData = translations["en"];
  await fs.writeFile(langEnPath, JSON.stringify(langEnData, null, 2));

  for (let lang of langRest) {
    const langPath = `${langDir}/${kind}.${lang}.json`;
    const langData = translations[lang];
    const langPack = JSON.stringify(langData, null, 2);

    await fs.writeFile(langPath, langPack);

    // alias zh-cn
    if (kind === "bundle.l10n" && lang === "zh") {
      const langZhCNPath = `${langDir}/${kind}.zh-cn.json`;
      await fs.writeFile(langZhCNPath, langPack);
    }
  }

  return translations;
}

// todo: verify using rust
export async function genVscodeExt() {
  const translations = await translate("editors/vscode", "package.nls", [
    "locales/tinymist-vscode.toml",
  ]);
  await translate("editors/vscode/l10n", "bundle.l10n", ["locales/tinymist-vscode-rt.toml"]);

  const pat = /\%(extension\.tinymist\..*?)\%/g;
  const data = await fs.readFile(path.resolve(projectRoot, "editors/vscode/package.json"), "utf-8");
  const matchAll = data.matchAll(pat);
  const used = Array.from(matchAll).map((m) => m[1]);
  used.push("description");

  const en = translations["en"];
  const enKeys = Object.keys(en);
  const missing = used.filter((key) => !enKeys.includes(key));
  if (missing.length > 0) {
    console.error("Missing translations", missing);
  }
  const extra = enKeys.filter((key) => !used.includes(key));
  if (extra.length > 0) {
    console.error("Extra translations", extra);
  }

  return translations;
}
