import { promises as fs } from "node:fs";
import { dirname } from "node:path";
function setAtPath(obj, keyPath, value) {
  let cursor = obj;
  for (let i = 0; i < keyPath.length - 1; i++) {
    const k = keyPath[i];
    if (typeof cursor[k] !== "object" || cursor[k] === null || Array.isArray(cursor[k])) {
      cursor[k] = {};
    }
    cursor = cursor[k];
  }
  cursor[keyPath[keyPath.length - 1]] = value;
}
async function fileReadable(path) {
  try {
    await fs.access(path);
    return true;
  } catch {
    return false;
  }
}
async function writeJsonConfig(args) {
  const { path, keyPath, entry, dryRun } = args;
  let existing = {};
  const exists = await fileReadable(path);
  if (exists) {
    try {
      const raw = await fs.readFile(path, "utf-8");
      const trimmed = raw.trim();
      if (trimmed.length > 0) {
        const parsed = JSON.parse(trimmed);
        if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
          existing = parsed;
        } else {
          return { ok: false, code: "PARSE_ERROR", message: "existing config is not a JSON object" };
        }
      }
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      return { ok: false, code: "PARSE_ERROR", message: `unable to parse existing JSON: ${message}` };
    }
  }
  setAtPath(existing, keyPath, entry);
  const json = JSON.stringify(existing, null, 2) + "\n";
  if (dryRun) {
    return { ok: true, code: "OK", dryRun: true };
  }
  try {
    await fs.mkdir(dirname(path), { recursive: true });
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    if (/EACCES|EPERM/.test(message)) {
      return { ok: false, code: "PERMISSION_DENIED", message };
    }
    return { ok: false, code: "MKDIR_FAILED", message };
  }
  let backupPath;
  if (exists) {
    backupPath = `${path}.bak`;
    try {
      await fs.copyFile(path, backupPath);
    } catch {
      backupPath = void 0;
    }
  }
  const tmpPath = `${path}.tmp`;
  try {
    await fs.writeFile(tmpPath, json, "utf-8");
    await fs.rename(tmpPath, path);
    return { ok: true, code: "OK", backupPath };
  } catch (err) {
    const message = err instanceof Error ? err.message : String(err);
    try {
      await fs.unlink(tmpPath);
    } catch {
    }
    if (/EACCES|EPERM/.test(message)) {
      return { ok: false, code: "PERMISSION_DENIED", message };
    }
    return { ok: false, code: "WRITE_FAILED", message };
  }
}
export {
  writeJsonConfig
};
//# sourceMappingURL=config-writer-json.js.map