import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join, resolve } from "node:path";

import {
  fileSha256,
  readJson,
  validateCandidateReference,
  validateResendEvidence,
} from "./lib/resend-release-gate.mjs";

const phaseIndex = process.argv.indexOf("--phase");
const phase = phaseIndex >= 0 ? process.argv[phaseIndex + 1] : "green";
if (!new Set(["red", "green"]).has(phase)) throw new Error(`Unsupported phase: ${phase}`);

const candidateRunId = process.env.DADA_WP7_01_RUN_ID ?? "wp7-01-candidate-20260804052447717";
const runId = process.env.DADA_TDD_RUN_ID ?? `wp7-03-${phase}-${new Date().toISOString().replace(/[^0-9]/g, "")}`;
const runDirectory = resolve("artifacts", "tdd", runId);
const caseId = "TDD-WP7-EXT-002-real-resend";
const caseDirectory = resolve(runDirectory, "cases", caseId);
if (existsSync(runDirectory)) throw new Error(`Evidence run already exists: ${runId}`);
mkdirSync(caseDirectory, { recursive: true });

function writeJson(path, value) {
  writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
}

function runCommand(name, command) {
  const startedAt = new Date().toISOString();
  const result = spawnSync(process.env.ComSpec ?? "cmd.exe", ["/d", "/s", "/c", command], {
    encoding: "utf8",
    env: process.env,
    maxBuffer: 40 * 1024 * 1024,
    stdio: "inherit",
  });
  return {
    command,
    exit_code: result.status ?? 1,
    finished_at: new Date().toISOString(),
    name,
    started_at: startedAt,
  };
}

const candidateEvidenceRoot = resolve(
  process.env.DADA_WP7_01_EVIDENCE_DIR ?? join("artifacts", "tdd", candidateRunId),
);
const candidate = readJson(join(candidateEvidenceRoot, "release-candidate.json"));
const candidateErrors = candidate ? validateCandidateReference(candidate) : ["candidate_record_missing"];
writeJson(resolve(caseDirectory, "candidate-reference.json"), candidate ? {
  browsers: candidate.browsers.map(({ brand, full_version: fullVersion, major }) => ({ brand, full_version: fullVersion, major })),
  build_commit: candidate.build_commit,
  candidate_status: candidate.status,
  final_release: candidate.final_release,
  fixed_port: candidate.fixed_port,
  run_id: candidateRunId,
  schema_version: "1.0",
} : {
  candidate_status: "not_available",
  reason: "candidate_record_missing",
  run_id: candidateRunId,
  schema_version: "1.0",
});

const commands = phase === "red" ? [] : [
  ["workspace-build", "pnpm build:workspace-packages"],
  ["integration", "pnpm test:integration"],
  ["api", "pnpm check:openapi && pnpm exec vitest run tests/api --maxWorkers=1"],
  ["security", "pnpm test:security"],
  ["tdd-trace", "pnpm validate:tdd-trace"],
].map(([name, command]) => runCommand(name, command));
const localGatePassed = phase === "red" || commands.length > 0 && commands.every(({ exit_code }) => exit_code === 0);

const redaction = {
  absolute_paths_in_evidence: false,
  credentials_in_evidence: false,
  forbidden_matches: 0,
  mailboxes_in_evidence: false,
  private_content_in_evidence: false,
  schema_version: "1.0",
  status: "passed",
};
const externalRoot = process.env.DADA_RESEND_EVIDENCE_DIR ? resolve(process.env.DADA_RESEND_EVIDENCE_DIR) : undefined;
const realAuthorized = process.env.DADA_RESEND_REAL_AUTHORIZED === "1";
const externalFiles = ["domain-check.json", "delivery-summary.json", "auth-result.json", "redaction.json"];
const externalEvidence = externalRoot
  ? Object.fromEntries(externalFiles.map((file) => [file, readJson(join(externalRoot, file))]))
  : {};
const externalEvidenceMissing = externalRoot ? externalFiles.filter((file) => !externalEvidence[file]) : externalFiles;
const externalErrors = externalRoot && externalEvidenceMissing.length === 0 && candidate
  ? validateResendEvidence({
      authResult: externalEvidence["auth-result.json"],
      candidate,
      deliverySummary: externalEvidence["delivery-summary.json"],
      domainCheck: externalEvidence["domain-check.json"],
      redaction: externalEvidence["redaction.json"],
    })
  : [];

const externalBlockers = [];
if (candidateErrors.length > 0) externalBlockers.push("candidate_record_unavailable_or_drifted");
if (!realAuthorized) externalBlockers.push("controlled_domain_or_real_mailbox_authorization_absent");
if (!externalRoot) externalBlockers.push("real_resend_evidence_not_supplied");
if (externalRoot && externalEvidenceMissing.length > 0) externalBlockers.push("real_resend_evidence_incomplete");
if (externalErrors.length > 0) externalBlockers.push("real_resend_evidence_invalid");

if (phase === "red") {
  writeJson(resolve(caseDirectory, "red-observation.json"), {
    expected_failure: "Resend SPF/DKIM, free-rule, delivery, and formal authentication evidence is absent before TASK-WP7-03.",
    observed_commands: ["pnpm test:wp7-03:red"],
    red_reason: "TDD-WP7-EXT-002 requires controlled real domain/mailbox evidence; mock or pre-seeded accounts are not release evidence.",
    status: "red_confirmed",
  });
} else if (externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0) {
  for (const file of externalFiles) writeJson(resolve(caseDirectory, file), externalEvidence[file]);
  writeJson(resolve(caseDirectory, "source-hashes.json"), {
    files: Object.fromEntries(externalFiles.map((file) => [file, fileSha256(join(externalRoot, file))])),
    schema_version: "1.0",
  });
} else {
  writeJson(resolve(caseDirectory, "blocker.json"), {
    blockers: externalErrors.length > 0 ? ["real_resend_evidence_invalid"] : externalBlockers,
    mock_accepted_as_evidence: false,
    paid_fallback_enabled: false,
    preseeded_accounts_accepted_as_evidence: false,
    real_calls_started: false,
    schema_version: "1.0",
    status: "externally_blocked",
  });
  writeJson(resolve(caseDirectory, "redaction.json"), redaction);
  writeJson(resolve(caseDirectory, "source-hashes.json"), { files: {}, schema_version: "1.0" });
}

const expectedEvidence = phase === "red"
  ? ["candidate-reference.json", "red-observation.json"]
  : externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0
    ? ["candidate-reference.json", "domain-check.json", "delivery-summary.json", "auth-result.json", "redaction.json", "source-hashes.json"]
    : ["candidate-reference.json", "blocker.json", "redaction.json", "source-hashes.json"];
const missingEvidence = expectedEvidence.filter((file) => !existsSync(resolve(caseDirectory, file)));
const status = phase === "red"
  ? localGatePassed && missingEvidence.length === 0 ? "red_confirmed" : "failed"
  : !localGatePassed || missingEvidence.length > 0 ? "failed"
    : realAuthorized && (!externalRoot || externalEvidenceMissing.length > 0 || externalErrors.length > 0) ? "failed"
    : externalRoot && externalEvidenceMissing.length === 0 && candidateErrors.length === 0 && realAuthorized && externalErrors.length === 0 ? "passed"
      : "externally_blocked";
const manifest = {
  path: "tasks.manifest.json",
  sha256: createHash("sha256").update(readFileSync("tasks.manifest.json")).digest("hex").toUpperCase(),
};
const result = {
  acceptance_criteria: ["AC-01", "AC-33", "AC-41", "AC-47", "AC-49"],
  automation: ["controlled_real", "manual_review"],
  candidate_run_id: candidateRunId,
  commit: spawnSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).stdout.trim(),
  evidence_refs: expectedEvidence,
  external_blockers: phase === "green" && status === "externally_blocked" ? externalBlockers : [],
  finished_at: new Date().toISOString(),
  layer: ["EXT-REAL", "MANUAL"],
  manifest,
  missing_evidence: missingEvidence,
  phase,
  requirements: ["AUTH-01", "AUTH-02", "AUTH-07"],
  run_id: runId,
  schema_version: "1.0",
  status,
  task_id: "TASK-WP7-03",
  test_id: caseId,
  work_package: "WP-7",
};
writeJson(resolve(caseDirectory, "commands.json"), { commands, phase, run_id: runId, schema_version: "1.0" });
writeJson(resolve(caseDirectory, "result.json"), result);
writeJson(resolve(runDirectory, "evidence.json"), { cases: [{ external_blockers: result.external_blockers, missing_evidence: missingEvidence, status, test_id: caseId }], phase, run_id: runId, status });
console.log(JSON.stringify({ external_blockers: result.external_blockers, phase, run_id: runId, status }, null, 2));
if (status === "failed") process.exit(1);
