import { createHash } from "node:crypto";
import { shq } from "./remote-ssh.mjs";
import { shellPathAssign } from "./home-path.mjs";

export function contentDigest(content) {
  const buf = Buffer.isBuffer(content) ? content : Buffer.from(String(content), "utf8");
  return createHash("sha256").update(buf).digest("hex");
}

export function buildAtomicWriteFromB64Script({ finalPath, content, mode = "600", label = "atomic" }) {
  const buf = Buffer.isBuffer(content) ? content : Buffer.from(String(content), "utf8");
  const digest = contentDigest(buf);
  const b64 = buf.toString("base64");
  return [
    "set -euo pipefail",
    shellPathAssign("final", finalPath),
    `want=${shq(digest)}`,
    "tmp=$(mktemp)",
    `python3 -c 'import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.argv[1]))' ${shq(b64)} >"$tmp"`,
    "actual=$(sha256sum \"$tmp\" | awk '{print $1}')",
    `[ "$actual" = "$want" ] || { echo ${shq(`${label}-digest`)}; exit 1; }`,
    "mv -f \"$tmp\" \"$final.tmp\"",
    `chmod ${mode} "$final.tmp"`,
    "mv -f \"$final.tmp\" \"$final\"",
    `chmod ${mode} "$final"`,
    "actual=$(sha256sum \"$final\" | awk '{print $1}')",
    `[ "$actual" = "$want" ] || { echo ${shq(`${label}-readback`)}; exit 1; }`,
  ].join("\n");
}

export function buildAtomicWriteIdempotentScript({ finalPath, content, mode = "600", label = "atomic" }) {
  const write = buildAtomicWriteFromB64Script({ finalPath, content, mode, label });
  return [
    "set -euo pipefail",
    shellPathAssign("final", finalPath),
    `want=${shq(contentDigest(content))}`,
    "if [ -f \"$final\" ]; then",
    "  actual=$(sha256sum \"$final\" | awk '{print $1}')",
    "  if [ \"$actual\" = \"$want\" ]; then exit 0; fi",
    "  echo atomic-existing-drift >&2",
    "  exit 1",
    "fi",
    write,
  ].join("\n");
}
