#!/usr/bin/env node
/**
 * 合同管理工具 — 完整 E2E 生成 + 验证
 * 使用 Certified Software Generator v1.1 的标准 Pipeline
 * 不修改任何 Generator 源码
 */

import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
import { resolve, dirname, join } from "node:path";
import { execSync } from "node:child_process";
import { fileURLToPath } from "node:url";

const __dirname = dirname(resolve(fileURLToPath(import.meta.url)));
const WORKSPACE = resolve(__dirname, "..");
const SCRIPTS = resolve(WORKSPACE, "scripts");
const B = resolve(WORKSPACE, ".benchmark", "contract-mgmt");

const INPUT = "开发一个合同管理桌面工具，支持合同创建、合同审批、合同到期提醒、客户管理、合同金额统计、操作日志";

mkdirSync(B, { recursive: true });

function cmd(c, opts = {}) {
  try {
    return execSync(c, { cwd: WORKSPACE, encoding: "utf8", ...opts, stdio: opts.stdio ?? "pipe" });
  } catch (e) {
    return { error: e.message, stderr: e.stderr?.toString() || "", stdout: e.stdout?.toString() || "" };
  }
}

function runAgent(script, args) {
  const t0 = Date.now();
  const result = cmd(`node ${join(SCRIPTS, script)} ${args}`);
  const ms = Date.now() - t0;
  if (result.error) {
    try { return { ms, ...JSON.parse(result.stdout?.trim() || "{}") }; } catch { return { ms, error: result.error }; }
  }
  try { return { ms, ...JSON.parse(result.trim()) }; } catch { return { ms, raw: result }; }
}

function countFiles(dir) {
  try {
    return parseInt(execSync(`find ${dir} -type f 2>/dev/null | wc -l`, { encoding: "utf8", cwd: WORKSPACE }).trim(), 10);
  } catch { return 0; }
}

// Validation functions (same as e2e-benchmark-v1.mjs)
function validateFrontend(dir) {
  if (!existsSync(dir)) return { pass: false, reason: "dir missing" };
  const checks = {
    packageJson: existsSync(join(dir, "package.json")),
    appDir: existsSync(join(dir, "app")),
    services: existsSync(join(dir, "services")) || existsSync(join(dir, "src", "services")),
    types: existsSync(join(dir, "types")) || existsSync(join(dir, "src", "types")),
  };
  const fileCount = countFiles(dir);
  return { pass: checks.packageJson && checks.appDir && fileCount > 10, fileCount, ...checks };
}

function validateBackend(dir) {
  if (!existsSync(dir)) return { pass: false, reason: "dir missing" };
  const checks = {
    packageJson: existsSync(join(dir, "package.json")),
    routes: existsSync(join(dir, "src", "routes")),
    services: existsSync(join(dir, "src", "services")),
    auth: existsSync(join(dir, "src", "routes", "auth.ts")) || existsSync(join(dir, "src", "routes", "auth-route.ts")),
    db: existsSync(join(dir, "src", "db")) || existsSync(join(dir, "src", "schema")),
  };
  const fileCount = countFiles(dir);
  return { pass: checks.packageJson && checks.routes && checks.services && fileCount > 10, fileCount, ...checks };
}

function validateFullstack(dir) {
  if (!existsSync(dir)) return { pass: false, reason: "dir missing" };
  const checks = {
    packageJson: existsSync(join(dir, "package.json")),
    web: existsSync(join(dir, "apps", "web")),
    api: existsSync(join(dir, "apps", "api")),
    shared: existsSync(join(dir, "packages")),
  };
  const fileCount = countFiles(dir);
  return { pass: checks.packageJson && checks.web && checks.api && fileCount > 30, fileCount, ...checks };
}

function validateElectron(dir) {
  if (!existsSync(dir)) return { pass: false, reason: "dir missing" };
  const checks = {
    packageJson: existsSync(join(dir, "package.json")),
    main: existsSync(join(dir, "electron", "main.ts")),
    preload: existsSync(join(dir, "electron", "preload.ts")),
    ipc: existsSync(join(dir, "electron", "ipc.ts")),
    yml: existsSync(join(dir, "electron-builder.yml")),
  };
  const fileCount = countFiles(dir);
  return { pass: checks.packageJson && checks.main && checks.preload && fileCount >= 8, fileCount, ...checks };
}

function validateRelease(dir) {
  if (!existsSync(dir)) return { pass: false, reason: "dir missing" };
  const rDir = join(dir, "release");
  const checks = {
    versionJson: existsSync(join(rDir, "version.json")),
    manifest: existsSync(join(rDir, "manifests", "manifest.json")),
    checksums: existsSync(join(rDir, "checksums", "checksums.txt")),
    releaseNotes: existsSync(join(rDir, "release-notes", "release-notes.md")),
    buildInfo: existsSync(join(rDir, "build-info.json")),
  };
  if (checks.checksums) {
    const lines = readFileSync(join(rDir, "checksums", "checksums.txt"), "utf8").trim().split("\n").filter(l => l.length > 0);
    checks.checksumCount = lines.length;
    checks.checksumsValid = lines.every(l => l.split(/\s+/)[0]?.length === 64);
  }
  if (checks.buildInfo) {
    try {
      const bi = JSON.parse(readFileSync(join(rDir, "build-info.json"), "utf8"));
      checks.buildInfoValid = !!(bi.nodeVersion && bi.generatorVersion);
    } catch { checks.buildInfoValid = false; }
  }
  const fileCount = countFiles(dir);
  return { pass: checks.versionJson && checks.manifest && checks.checksums && checks.releaseNotes && checks.buildInfo, fileCount, ...checks };
}

// ═══════════════════════════════════════════════════════
// MAIN
// ═══════════════════════════════════════════════════════

console.log("═".repeat(60));
console.log("  合同管理工具 — Certified Generator v1.1 E2E 验证");
console.log("═".repeat(60));
console.log(`\n需求: ${INPUT}\n`);

// SF-01: PRD
console.log("▸ SF-01 Project Intake...");
const s1 = runAgent("project-intake-agent.mjs", `--input "${INPUT}" --output "${join(B, "prd.json")}"`);
console.log(`  ✓ PRD: ${s1.projectName || "?"} (${s1.ms}ms) ${s1.error ? "❌ " + s1.error : "✅"}`);

// SF-02: Architecture
console.log("▸ SF-02 Architecture...");
const s2 = runAgent("architecture-agent.mjs", `--input "${join(B, "prd.json")}" --output "${join(B, "arch.json")}"`);
console.log(`  ✓ Architecture: ${s2.moduleCount || "?"} modules (${s2.ms}ms) ${s2.error ? "❌ " + s2.error : "✅"}`);

// SF-03: Frontend
console.log("▸ SF-03 Frontend Builder...");
const feOut = join(B, "frontend");
const s3 = runAgent("frontend-builder-agent.mjs", `--prd "${join(B, "prd.json")}" --arch "${join(B, "arch.json")}" --output "${feOut}"`);
const feVal = validateFrontend(feOut);
console.log(`  ✓ Frontend: ${feVal.fileCount} files (${s3.ms}ms) ${feVal.pass ? "✅" : "❌"}`);

// SF-04: Backend
console.log("▸ SF-04 Backend Builder...");
const beOut = join(B, "backend");
const s4 = runAgent("backend-builder-agent.mjs", `--prd "${join(B, "prd.json")}" --arch "${join(B, "arch.json")}" --output "${beOut}"`);
const beVal = validateBackend(beOut);
console.log(`  ✓ Backend: ${beVal.fileCount} files (${s4.ms}ms) ${beVal.pass ? "✅" : "❌"}`);

// SF-05: Fullstack
console.log("▸ SF-05 Fullstack Composer...");
const fsOut = join(B, "fullstack");
const s5 = runAgent("fullstack-composer-agent.mjs", `--prd "${join(B, "prd.json")}" --arch "${join(B, "arch.json")}" --output "${fsOut}"`);
const fsVal = validateFullstack(fsOut);
console.log(`  ✓ Fullstack: ${fsVal.fileCount} files (${s5.ms}ms) ${fsVal.pass ? "✅" : "❌"}`);

// SF-06: Electron
console.log("▸ SF-06 Electron Builder...");
const elOut = join(B, "electron");
const s6 = runAgent("electron-builder-agent.mjs", `--input "${fsOut}" --output "${elOut}" --prd "${join(B, "prd.json")}"`);
const elVal = validateElectron(elOut);
console.log(`  ✓ Electron: ${elVal.fileCount} files (${s6.ms}ms) ${elVal.pass ? "✅" : "❌"}`);

// SF-07: Release
console.log("▸ SF-07 Release Builder...");
const rlOut = join(B, "release");
const s7 = runAgent("release-builder-agent.mjs", `--input "${fsOut}" --output "${rlOut}"`);
const rlVal = validateRelease(rlOut);
console.log(`  ✓ Release: ${rlVal.fileCount} files (${s7.ms}ms) ${rlVal.pass ? "✅" : "❌"}`);

// Summary
const totalMs = s1.ms + s2.ms + s3.ms + s4.ms + s5.ms + s6.ms + s7.ms;
const totalFiles = (s3.stats?.totalFiles || feVal.fileCount) + (s4.stats?.totalFiles || beVal.fileCount) + (s5.stats?.totalFiles || fsVal.fileCount) + (s6.stats?.totalFiles || elVal.fileCount) + (s7.stats?.totalFiles || rlVal.fileCount);
const allPass = feVal.pass && beVal.pass && fsVal.pass && elVal.pass && rlVal.pass;

console.log("\n" + "═".repeat(60));
console.log(`  总计: ${totalFiles} files | ${totalMs}ms | ${allPass ? "✅ ALL PASS" : "❌ HAS FAILURES"}`);
console.log("═".repeat(60));

// Output summary as JSON
const summary = {
  input: INPUT,
  projectName: s1.projectName,
  domain: s1.domain,
  stages: {
    prd: { ms: s1.ms, error: s1.error },
    arch: { ms: s2.ms, modules: s2.moduleCount, error: s2.error },
    frontend: { ms: s3.ms, files: feVal.fileCount, pass: feVal.pass, error: s3.error },
    backend: { ms: s4.ms, files: beVal.fileCount, pass: beVal.pass, error: s4.error },
    fullstack: { ms: s5.ms, files: fsVal.fileCount, pass: fsVal.pass, error: s5.error },
    electron: { ms: s6.ms, files: elVal.fileCount, pass: elVal.pass, error: s6.error },
    release: { ms: s7.ms, files: rlVal.fileCount, pass: rlVal.pass, error: s7.error },
  },
  totalMs,
  totalFiles,
  allPass,
  outputDir: B,
};

writeFileSync(join(B, "summary.json"), JSON.stringify(summary, null, 2));
console.log(`\nSummary: ${join(B, "summary.json")}`);
