import { DatabaseSync, backup } from "node:sqlite";
import { existsSync, mkdirSync, chmodSync, readFileSync } from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
if (!process.argv[2] || !process.argv[3])
  throw new Error("Usage: node scripts/restore.mjs BACKUP NEW_DATABASE_PATH");
const source = path.resolve(process.argv[2]),
  target = path.resolve(process.argv[3]);
if (!existsSync(source) || existsSync(target))
  throw new Error(
    "Source must exist; destination must be a new file. Restore never overwrites a database.",
  );
if (existsSync(source + ".sha256")) {
  const actual = crypto
    .createHash("sha256")
    .update(readFileSync(source))
    .digest("hex");
  if (actual !== readFileSync(source + ".sha256", "utf8").trim())
    throw new Error("Backup checksum mismatch.");
}
mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
const db = new DatabaseSync(source, { readOnly: true });
if (
  db.prepare("PRAGMA integrity_check").get().integrity_check !== "ok" ||
  db.prepare("PRAGMA foreign_key_check").all().length
)
  throw new Error("Source integrity checks failed.");
await backup(db, target);
db.close();
chmodSync(target, 0o600);
const check = new DatabaseSync(target, { readOnly: true });
const mismatches = check
  .prepare(
    "SELECT l.id FROM lots l WHERE l.quantity <> COALESCE((SELECT SUM(m.quantity) FROM movements m WHERE m.lot=l.id),0)",
  )
  .all();
if (mismatches.length)
  throw new Error(
    `Restored stock ledger has ${mismatches.length} mismatches; do not switch the service to this file.`,
  );
const records = check.prepare("SELECT COUNT(*) n FROM products").get().n;
check.close();
console.log(
  JSON.stringify({
    restored: target,
    verified: true,
    products: records,
    instruction:
      "Stop the application, set DB_PATH to this restored file, restart, and verify an actual product in the UI.",
  }),
);
