import { loadTextFile, saveTextFile } from "./file-service.js";
import { parameterFilePath } from "./path-model.js";

const DEFAULT_WASM_PARAMETER_PATH = "/work/linuxcnc.var";

function requireParameterSdk(interp) {
  for (const method of ["writeTextFile", "readTextFile", "restoreParameters", "saveParameters"]) {
    if (typeof interp?.[method] !== "function") {
      throw new Error(`interpreter SDK is missing ${method}().`);
    }
  }
}

function resolvePaths(machineId, options = {}) {
  const opfsPath = options.opfsPath ?? parameterFilePath(machineId, options.filename);
  const wasmPath = options.wasmPath ?? DEFAULT_WASM_PARAMETER_PATH;
  return { opfsPath, wasmPath };
}

function readOptionalWasmTextFile(interp, path) {
  try {
    return interp.readTextFile(path);
  } catch {
    return null;
  }
}

export async function restoreMachineParametersFromOpfs(interp, machineId, options = {}) {
  requireParameterSdk(interp);
  const { opfsPath, wasmPath } = resolvePaths(machineId, options);
  const text = await loadTextFile(opfsPath, options.storage);
  interp.writeTextFile(wasmPath, text);
  return {
    opfsPath,
    wasmPath,
    result: interp.restoreParameters(wasmPath),
  };
}

export async function saveMachineParametersToOpfs(interp, machineId, values, options = {}) {
  requireParameterSdk(interp);
  const { opfsPath, wasmPath } = resolvePaths(machineId, options);
  const existingText = await loadTextFile(opfsPath, options.storage);
  interp.writeTextFile(wasmPath, existingText);

  const result = interp.saveParameters(wasmPath, values);
  const savedText = interp.readTextFile(wasmPath);
  const backupText = readOptionalWasmTextFile(interp, `${wasmPath}.bak`);

  await saveTextFile(opfsPath, savedText, options.storage);
  if (backupText !== null) {
    await saveTextFile(`${opfsPath}.bak`, backupText, options.storage);
  }

  return {
    opfsPath,
    backupOpfsPath: backupText === null ? null : `${opfsPath}.bak`,
    wasmPath,
    result,
    savedText,
    backupText,
  };
}
