import fs from "node:fs";
import path from "node:path";
import process from "node:process";

const repoRoot = process.cwd();
const mediaExtensions = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif", ".mp4", ".mov", ".webm", ".avif"]);
const textExtensions = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json", ".html", ".css", ".md", ".env", ".example"]);

const scanRoots = ["src", "vite.config.ts", "index.html", "package.json", ".env.example"];
const allowedFiles = new Set([
  normalizePath("src/data/ossAssets.ts"),
  normalizePath("src/utils/ossImageOptimize.ts"),
]);

const forbiddenPatterns = [
  { label: "frontend env config", pattern: /\b(?:import\.meta\.env|VITE_[A-Z0-9_]+)\b/ },
  { label: "direct provider proxy", pattern: /\/dashscope-api\b|dashscope\.aliyuncs\.com/i },
  { label: "third-party demo media host", pattern: /picsum\.photos|xiuxiu-pro(?:-new)?\.meitudata\.com|meitudata\.com/i },
  { label: "hard-coded provider secret marker", pattern: /Bearer\s+sk-|DASHSCOPE_API_KEY|ACCESS_KEY_SECRET|SECRET_ACCESS_KEY/i },
  { label: "local media import", pattern: /from\s+["'][^"']*\/assets\/[^"']*\.(?:png|jpe?g|webp|gif|mp4|mov|webm|avif|svg)["']/i },
];

const failures = [];

function normalizePath(value) {
  return value.replace(/\\/g, "/");
}

function walk(targetPath, visitor) {
  if (!fs.existsSync(targetPath)) return;
  const stat = fs.statSync(targetPath);
  if (stat.isDirectory()) {
    for (const entry of fs.readdirSync(targetPath)) {
      if (entry === "node_modules" || entry === "dist" || entry === ".git") continue;
      walk(path.join(targetPath, entry), visitor);
    }
    return;
  }
  visitor(targetPath, stat);
}

function report(file, message) {
  failures.push(`${normalizePath(path.relative(repoRoot, file))}: ${message}`);
}

walk(path.join(repoRoot, "src", "assets"), (file) => {
  if (mediaExtensions.has(path.extname(file).toLowerCase())) {
    report(file, "media files must live in OSS, not src/assets");
  }
});

for (const root of scanRoots) {
  walk(path.join(repoRoot, root), (file) => {
    const relative = normalizePath(path.relative(repoRoot, file));
    const ext = path.extname(file).toLowerCase();
    if (!textExtensions.has(ext) && !relative.endsWith(".env.example")) return;
    if (relative.startsWith("src/assets/")) return;

    const content = fs.readFileSync(file, "utf8");
    const isAllowed = allowedFiles.has(relative);
    for (const rule of forbiddenPatterns) {
      if (isAllowed && (rule.label === "third-party demo media host" || rule.label === "hard-coded provider secret marker")) {
        continue;
      }
      if (rule.pattern.test(content)) {
        report(file, `forbidden ${rule.label}`);
      }
    }
  });
}

if (failures.length) {
  console.error("Governance check failed:");
  for (const failure of failures) {
    console.error(`- ${failure}`);
  }
  process.exit(1);
}

console.log("Governance check passed.");
