import { createHash } from "crypto";
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
import { join, relative } from "path";
const HASHES_DIR = ".specverse-gen";
const HASHES_FILE = "hashes.json";
function sha256(s) {
  return createHash("sha256").update(s, "utf8").digest("hex");
}
function loadHashManifest(projectRoot) {
  const path = join(projectRoot, HASHES_DIR, HASHES_FILE);
  if (!existsSync(path)) return {};
  try {
    const raw = readFileSync(path, "utf8");
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
      const out = {};
      for (const [k, v] of Object.entries(parsed)) {
        if (typeof v === "string") out[k] = v;
      }
      return out;
    }
  } catch {
  }
  return {};
}
function saveHashManifest(projectRoot, manifest) {
  const dir = join(projectRoot, HASHES_DIR);
  mkdirSync(dir, { recursive: true });
  const path = join(dir, HASHES_FILE);
  writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n", "utf8");
}
function reconcileWrites(projectRoot, proposed, prevManifest) {
  const manifest = { ...prevManifest };
  const approvedWrites = {};
  const skipped = [];
  for (const [relPath, content] of Object.entries(proposed)) {
    const abs = join(projectRoot, relPath);
    const newHash = sha256(content);
    if (!existsSync(abs)) {
      approvedWrites[relPath] = content;
      manifest[relPath] = newHash;
      continue;
    }
    const currentContent = readFileSync(abs, "utf8");
    const currentHash = sha256(currentContent);
    const recordedHash = prevManifest[relPath];
    if (recordedHash == null) {
      skipped.push({
        path: relPath,
        reason: "no prior hash recorded \u2014 cannot confirm this file was generated by us"
      });
      continue;
    }
    if (currentHash === recordedHash) {
      approvedWrites[relPath] = content;
      manifest[relPath] = newHash;
      continue;
    }
    skipped.push({
      path: relPath,
      reason: "file has been edited since last generation"
    });
  }
  return { approvedWrites, skipped, manifest };
}
function summarize(result, projectRoot) {
  const lines = [];
  const writeCount = Object.keys(result.approvedWrites).length;
  lines.push(`[ReactAppStarter] Approved ${writeCount} file(s) for writing.`);
  if (result.skipped.length > 0) {
    lines.push(`[ReactAppStarter] Skipped ${result.skipped.length} user-edited file(s):`);
    for (const { path, reason } of result.skipped) {
      lines.push(`  - ${path} (${reason})`);
    }
    lines.push(
      `To accept upstream regeneration for a skipped file, delete it (\`rm ${relative(process.cwd(), projectRoot)}/PATH\`) and re-run \`spv realize\`.`
    );
  }
  return lines.join("\n");
}
export {
  HASHES_DIR,
  HASHES_FILE,
  loadHashManifest,
  reconcileWrites,
  saveHashManifest,
  sha256,
  summarize
};
