// do the XML parsing and fs access in a build step

import { promises as fs } from "node:fs";
import * as path from "node:path";
import { XMLParser } from "fast-xml-parser";

const KEYBOARD_PATH = "../../../keyboards/3.0";
const IMPORT_PATH = "../../../keyboards/import";
const DATA_PATH = "static/data";

async function xmlList(basepath) {
  const dir = await fs.opendir(basepath);
  const xmls = [];
  for await (const ent of dir) {
    if (!ent.isFile() || !/\.xml$/.test(ent.name)) {
      continue;
    }
    xmls.push(ent.name);
  }
  return xmls;
}

/**
 * List of elements that are always arrays
 */
const alwaysArray = [
  "keyboard3.transforms",
  "keyboard3.transforms.transformGroup",
  "keyboard3.transforms.transformGroup.transform",
];

/**
 * Loading helper for isArray
 * @param name
 * @param jpath
 * @param isLeafNode
 * @param isAttribute
 * @returns
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const isArray = (name, jpath, isLeafNode, isAttribute) => {
  if (alwaysArray.indexOf(jpath) !== -1) return true;
  return false;
};

/**
 * Do the XML Transform given raw XML source
 * @param xml XML source for transforms. entire keyboard file.
 * @param source source text
 * @returns target text
 */
export function parseXml(xml) {
  const parser = new XMLParser({
    ignoreAttributes: false,
    isArray,
  });
  const j = parser.parse(xml);
  return j;
}

async function readFile(path) {
  return fs.readFile(path, "utf-8");
}

async function main() {
  const xmls = await xmlList(KEYBOARD_PATH);
  const keyboards = await packXmls(KEYBOARD_PATH, xmls);
  const importFiles = await xmlList(IMPORT_PATH);
  const imports = await packXmls(IMPORT_PATH, importFiles);

  const allData = {
    keyboards,
    imports,
  };

  const outPath = path.join(DATA_PATH, "keyboard-data.json");
  const outJsPath = path.join(DATA_PATH, "keyboard-data.js");
  await fs.mkdir(DATA_PATH, { recursive: true });
  const json = JSON.stringify(allData, null, " "); // indent, in case we need to read it
  await fs.writeFile(outPath, json, "utf-8");
  await fs.writeFile(outJsPath, `const _KeyboardData = \n` + json);
  return { xmls, importFiles, outPath, outJsPath };
}

main().then(
  (done) => console.dir({ done }),
  (err) => {
    console.error(err);
    process.exitCode = 1;
  }
);

async function packXmls(basepath, xmls) {
  const allData = {};
  for (const fn of xmls) {
    const fp = path.join(basepath, fn);
    const data = await readFile(fp);
    const parsed = parseXml(data);
    allData[fn] = parsed;
  }
  return allData;
}
