import type { Command } from "commander";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { compileFile } from "../core/compiler.js";
import { renderDiagnostic } from "./render-diagnostics.js";
import { shouldUseColor } from "./color.js";

export function registerValidate(program: Command) {
  program
    .command("validate")
    .description("Validate a TypeScript intent definition without generating output")
    .argument("<file>", "Path to the TypeScript intent definition")
    .option(
      "--sandbox",
      "Run stage 4 validation: swift build in an SPM sandbox (macOS only)"
    )
    .action(async (file: string, options: { sandbox: boolean }) => {
      const filePath = resolve(file);
      const color = shouldUseColor();
      const paint = (ansi: string, text: string) =>
        color ? `${ansi}${text}\x1b[0m` : text;

      try {
        const result = compileFile(filePath, { validate: true });

        let sources: Map<string, string> | undefined;
        try {
          sources = new Map([[filePath, readFileSync(filePath, "utf-8")]]);
        } catch {
          sources = undefined;
        }

        for (const d of result.diagnostics) {
          console.error(renderDiagnostic(d, { color, sources }));
        }

        if (!result.success) {
          process.exit(1);
        }

        if (options.sandbox && result.output) {
          const { sandboxCompile } = await import("../core/sandbox.js");
          console.log(`${paint("\x1b[36m", "→")} Stage 4: SPM sandbox compile...`);
          const sandboxResult = await sandboxCompile(result.output.swiftCode, {
            intentName: result.output.ir.name,
          });
          if (!sandboxResult.ok) {
            console.error(`${paint("\x1b[31m", "✗")} ${sandboxResult.stderr}`);
            process.exit(1);
          }
          console.log(
            `${paint("\x1b[32m", "✓")} Valid intent definition (sandbox-verified, ${sandboxResult.durationMs}ms)`
          );
        } else {
          console.log(`${paint("\x1b[32m", "✓")} Valid intent definition`);
        }
      } catch (err: unknown) {
        if (
          err &&
          typeof err === "object" &&
          "format" in err &&
          typeof (err as Record<string, unknown>).format === "function"
        ) {
          console.error((err as { format: () => string }).format());
        } else {
          console.error(`${paint("\x1b[31m", "error:")} ${err}`);
        }
        process.exit(1);
      }
    });
}
