/**
 * Guard: no raw SiteConversion queries without countedConversionWhere
 * ────────────────────────────────────────────────────────────────────
 * Fails the build when a file contains a direct prisma.siteConversion
 * count/findMany/groupBy call that neither:
 *   (a) imports countedConversionWhere, nor
 *   (b) carries an explicit "// intentionally unfiltered:" comment on
 *       the same or immediately preceding line.
 *
 * Admin/debug/backfill endpoints that legitimately need raw rows MUST
 * add: // intentionally unfiltered: <reason>
 * to suppress the check.
 *
 * Run: node scripts/check-raw-siteconversion.mjs
 */

import { readFileSync, readdirSync, statSync } from "fs";
import { join, relative } from "path";

const ROOT = join(new URL(".", import.meta.url).pathname, "..");
const SRC = join(ROOT, "src");

const RAW_CALL_RE = /prisma\.siteConversion\.(count|findMany|groupBy|aggregate)\s*\(/g;
// Lines that are part of a comment block should not be flagged
const COMMENT_LINE_RE = /^\s*(\*|\/\/|\/\*)/;
const UNFILTERED_COMMENT_RE = /\/\/\s*intentionally unfiltered:/i;
const IMPORT_HELPER_RE = /import\s+[^;]*countedConversionWhere[^;]*from/;

function walkFiles(dir, results = []) {
  for (const entry of readdirSync(dir)) {
    const full = join(dir, entry);
    const stat = statSync(full);
    if (stat.isDirectory()) {
      // Skip node_modules and .next
      if (entry === "node_modules" || entry === ".next") continue;
      walkFiles(full, results);
    } else if (full.endsWith(".ts") || full.endsWith(".tsx")) {
      results.push(full);
    }
  }
  return results;
}

const files = walkFiles(SRC);
const violations = [];

for (const filePath of files) {
  const content = readFileSync(filePath, "utf8");
  const hasHelper = IMPORT_HELPER_RE.test(content);
  const lines = content.split("\n");

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (!RAW_CALL_RE.test(line) || COMMENT_LINE_RE.test(line)) {
      RAW_CALL_RE.lastIndex = 0;
      continue;
    }
    RAW_CALL_RE.lastIndex = 0;

    // If the file imports countedConversionWhere, it's opted in — trust the author.
    if (hasHelper) continue;

    // Check for an intentionally-unfiltered comment on this line or the line above.
    const prevLine = i > 0 ? lines[i - 1] : "";
    if (UNFILTERED_COMMENT_RE.test(line) || UNFILTERED_COMMENT_RE.test(prevLine)) continue;

    violations.push(`  ${relative(ROOT, filePath)}:${i + 1}  →  ${line.trim().slice(0, 80)}`);
  }
}

if (violations.length > 0) {
  console.error("");
  console.error("╔══════════════════════════════════════════════════════════════════════╗");
  console.error("║  RAW SITECONVERSION CHECK FAILED                                     ║");
  console.error("╠══════════════════════════════════════════════════════════════════════╣");
  console.error("║  The following files query SiteConversion without using              ║");
  console.error("║  countedConversionWhere() or an explicit unfiltered comment.         ║");
  console.error("║                                                                      ║");
  console.error("║  User-facing conversion numbers MUST route through the helper so     ║");
  console.error("║  isDuplicateOf / invalidatedReason / EXCLUDED_CONVERSION_TYPES are   ║");
  console.error("║  applied consistently.                                               ║");
  console.error("║                                                                      ║");
  console.error("║  Fix options:                                                        ║");
  console.error("║    1. import { countedConversionWhere } from                         ║");
  console.error('║          "@/lib/conversions/counted-where"                           ║');
  console.error("║       and use it in the where clause.                               ║");
  console.error("║    2. Add: // intentionally unfiltered: <reason>                     ║");
  console.error("║       on the line before the query for debug/admin/backfill paths.  ║");
  console.error("╚══════════════════════════════════════════════════════════════════════╝");
  console.error("");
  violations.forEach((v) => console.error(v));
  console.error("");
  process.exit(1);
}

console.log(`[check-raw-siteconversion] OK — ${files.length} files checked, no violations.`);
process.exit(0);
