import createLinuxCncIniModule from "../../ui/ini-panel/linuxcnc_ini.js";

function allocCString(mod, value) {
  const bytes = mod.lengthBytesUTF8(value) + 1;
  const ptr = mod._malloc(bytes);
  mod.stringToUTF8(value, ptr, bytes);
  return ptr;
}

function ensureParentPath(mod, path) {
  const parts = path.split("/").filter(Boolean);
  let current = "";
  for (const part of parts.slice(0, -1)) {
    current += `/${part}`;
    try {
      mod.FS.mkdir(current);
    } catch {
      // Directory already exists.
    }
  }
}

export async function createLinuxCncIniSdk(moduleOptions = {}) {
  const mod = await createLinuxCncIniModule(moduleOptions);

  return {
    module: mod,

    writeTextFile(path, text) {
      ensureParentPath(mod, path);
      mod.FS.writeFile(path, text, { encoding: "utf8" });
    },

    getString(path, section, tag) {
      const pathPtr = allocCString(mod, path);
      const sectionPtr = allocCString(mod, section);
      const tagPtr = allocCString(mod, tag);
      const outSize = 2048;
      const outPtr = mod._malloc(outSize);

      try {
        const rc = mod._lcini_get_string(
          pathPtr,
          sectionPtr,
          tagPtr,
          outPtr,
          outSize,
        );
        return rc === 0 ? mod.UTF8ToString(outPtr) : null;
      } finally {
        mod._free(pathPtr);
        mod._free(sectionPtr);
        mod._free(tagPtr);
        mod._free(outPtr);
      }
    },

    getBool(path, section, tag) {
      const pathPtr = allocCString(mod, path);
      const sectionPtr = allocCString(mod, section);
      const tagPtr = allocCString(mod, tag);
      const outPtr = mod._malloc(4);

      try {
        const rc = mod._lcini_get_bool(pathPtr, sectionPtr, tagPtr, outPtr);
        return rc === 0 ? mod.HEAP32[outPtr >> 2] !== 0 : null;
      } finally {
        mod._free(pathPtr);
        mod._free(sectionPtr);
        mod._free(tagPtr);
        mod._free(outPtr);
      }
    },

    getFields(path, fields) {
      return Object.fromEntries(
        Object.entries(fields).map(([name, query]) => [
          name,
          this.getString(path, query.section, query.tag),
        ]),
      );
    },
  };
}
