import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { runAbb120SpecSuite } from "../src/suites/abb120SpecSuite.js";

const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const specRoot = join(webRoot, "tests", "fixtures", "abb120", "spec-programs");
const manifest = JSON.parse(readFileSync(join(specRoot, "manifest.json"), "utf8"));
const programs = manifest.programs.map((entry: { program_id: string; file: string }) => ({
  program_id: entry.program_id,
  file: entry.file,
  text: readFileSync(join(specRoot, entry.file), "utf8")
}));
const job = runAbb120SpecSuite(manifest, programs, {
  gitRevision: process.env.GIT_REVISION ?? "working-tree"
});
const outputRoot = resolve(webRoot, "test-results", "abb120-spec", job.job_id);

mkdirSync(outputRoot, { recursive: true });
writeFileSync(join(outputRoot, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
writeFileSync(join(outputRoot, "job.json"), `${JSON.stringify(job, null, 2)}\n`);
writeFileSync(join(outputRoot, "report.json"), `${JSON.stringify(reportJson(job), null, 2)}\n`);
writeFileSync(join(outputRoot, "report.html"), reportHtml(job));

for (const program of job.programs) {
  const programDir = join(outputRoot, "programs", program.program_id);
  mkdirSync(programDir, { recursive: true });
  writeFileSync(join(programDir, "compile.json"), `${JSON.stringify(program.compile, null, 2)}\n`);
  writeFileSync(join(programDir, "controller.json"), `${JSON.stringify(program.controller ?? {}, null, 2)}\n`);
  writeFileSync(join(programDir, "motion-queue.json"), `${JSON.stringify(program.motionQueue ?? {}, null, 2)}\n`);
  writeFileSync(join(programDir, "trace.json"), `${JSON.stringify(program.trace ?? [], null, 2)}\n`);
  writeFileSync(join(programDir, "io.json"), `${JSON.stringify(program.io ?? {}, null, 2)}\n`);
  writeFileSync(join(programDir, "trajectory.json"), `${JSON.stringify(program.trajectory ?? {}, null, 2)}\n`);
  writeFileSync(join(programDir, "post-report.json"), `${JSON.stringify(program.post ?? {}, null, 2)}\n`);
  writeFileSync(join(programDir, "roundtrip.json"), `${JSON.stringify(program.roundtrip ?? {}, null, 2)}\n`);
}

console.log(JSON.stringify({
  job_id: job.job_id,
  outputRoot,
  programs: job.programs.length,
  missingSections: job.coverage.missingSections
}, null, 2));

function reportJson(job: ReturnType<typeof runAbb120SpecSuite>) {
  return {
    job_id: job.job_id,
    suite_id: job.suite_id,
    robot_id: job.robot_id,
    coverage: job.coverage,
    summary: {
      programs: job.programs.length,
      pass: job.programs.filter((program) => program.status === "pass").length,
      diagnostic: job.programs.filter((program) => program.status === "diagnostic").length,
      fail: job.programs.filter((program) => program.status === "fail").length
    },
    diagnostics: job.programs.flatMap((program) =>
      program.diagnostics.map((diagnostic) => ({
        program_id: program.program_id,
        ...diagnostic
      }))
    )
  };
}

function reportHtml(job: ReturnType<typeof runAbb120SpecSuite>): string {
  const rows = job.programs.map((program) =>
    `<tr><td>${escapeHtml(program.program_id)}</td><td>${escapeHtml(program.coverage_level)}</td><td>${escapeHtml(program.status)}</td><td>${program.diagnostics.length}</td></tr>`
  ).join("\n");
  return `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>${escapeHtml(job.job_id)}</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 24px; color: #1f2933; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ccd5dd; padding: 8px; text-align: left; }
    th { background: #eef2f4; }
  </style>
</head>
<body>
  <h1>${escapeHtml(job.job_id)}</h1>
  <p>Suite ${escapeHtml(job.suite_id)} / Robot ${escapeHtml(job.robot_id)}</p>
  <p>Covered sections: ${job.coverage.coveredSections.join(", ")}</p>
  <table>
    <thead><tr><th>Program</th><th>Layer</th><th>Status</th><th>Diagnostics</th></tr></thead>
    <tbody>${rows}</tbody>
  </table>
</body>
</html>
`;
}

function escapeHtml(value: unknown): string {
  return String(value)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll("\"", "&quot;");
}
