// helper functions for keyboard

/**
 * Unescape an escaped string
 * @param str input string such as '\u017c'
 * @returns
 */
function unescapeStr(str) {
  str = str.replace(/\\u{([0-9a-fA-F]+)}/g, (a, b) =>
    String.fromCodePoint(Number.parseInt(b, 16))
  );
  return str;
}

function getKeyboardLayers(id) {
  let q = _KeyboardData.keyboards[id].keyboard3.layers;
  if (!Array.isArray(q)) {
    q = [q];
  }
  mogrifyAttrs(q);
  const keybag = getKeyboardKeys(id);
  mogrifyLayerList(q, keybag);
  return q;
}

function mogrifyLayerList(layerList, keybag) {
  layerList.forEach(({ layer }) => {
    layer.forEach(({ row }) => {
      row.forEach((r) => {
        r.keys = r.keys.split(" ").map((id) =>
          Object.assign(
            {
              id,
            },
            keybag[id]
          )
        );
      });
    });
  });
}

function getImportFile(id) {
  return _KeyboardData.imports[id["@_path"].split("/")[1]];
}

function getImportKeys(id) {
  const imp = getImportFile(id);
  if (!imp) {
    throw Error(`Could not load import ${JSON.stringify(id)}`);
  }
  return imp.keys.key;
}

function mogrifyKeys(keys) {
  // drop @'
  if (!keys) {
    return [];
  }
  return keys.reduce((p, v) => {
    // TODO: any other swapping
    mogrifyAttrs(v);
    const { id, output } = v;
    if (output) {
      v.output = unescapeStr(output);
    }
    p[id] = v;
    return p;
  }, {});
}

function mogrifyAttrs(o) {
  for (const k of Object.keys(o)) {
    const ok = o[k];
    if (/^@_/.test(k)) {
      const attr = k.substring(2);
      o[attr] = ok;
      delete o[k];
    } else if (Array.isArray(ok)) {
      ok.forEach((e) => mogrifyAttrs(e));
    } else if (typeof ok === "object") {
      mogrifyAttrs(ok);
    }
  }
  return o;
}

function getKeyboardKeys(id) {
  const keys = _KeyboardData.keyboards[id].keyboard3.keys.key || [];
  if (!keys) {
    throw Error(`No keys for ${id}`);
  }
  let imports = [
    {
      // add implied import
      "@_base": "cldr",
      "@_path": "45/keys-Latn-implied.xml",
    },
    ...(_KeyboardData.keyboards[id].keyboard3.keys.import || []),
  ];

  const importedKeys = [];
  for (const fn of imports) {
    for (const k of getImportKeys(fn)) {
      importedKeys.push(k);
    }
  }

  return mogrifyKeys([...importedKeys, ...keys]);
}

function getIds() {
  return Object.keys(_KeyboardData.keyboards);
}
