/**
 * Verification Evidence — JSON persistence and markdown table formatting.
 *
 * Two pure-ish functions:
 *   - writeVerificationJSON: persists a machine-readable T##-VERIFY.json artifact
 *   - formatEvidenceTable:   returns a markdown evidence table string
 *
 * JSON schema uses schemaVersion: 1 for forward-compatibility.
 * stdout/stderr are intentionally excluded from the JSON to avoid unbounded file sizes.
 */
import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
/**
 * Write a T##-VERIFY.json artifact to the tasks directory.
 * Creates the directory with mkdirSync({ recursive: true }) if it doesn't exist.
 *
 * stdout/stderr are excluded from the JSON — the full output lives in VerificationResult
 * in memory and is logged to stderr during the gate run.
 */
export function writeVerificationJSON(result, tasksDir, taskId, unitId, retryAttempt, maxRetries) {
    mkdirSync(tasksDir, { recursive: true });
    const evidence = {
        schemaVersion: 1,
        taskId,
        unitId: unitId ?? taskId,
        timestamp: result.timestamp,
        passed: result.passed,
        discoverySource: result.discoverySource,
        checks: result.checks.map((check) => ({
            command: check.command,
            exitCode: check.exitCode,
            durationMs: check.durationMs,
            verdict: check.exitCode === 0 ? "pass" : "fail",
        })),
        ...(retryAttempt !== undefined ? { retryAttempt } : {}),
        ...(maxRetries !== undefined ? { maxRetries } : {}),
    };
    if (result.runtimeErrors && result.runtimeErrors.length > 0) {
        evidence.runtimeErrors = result.runtimeErrors.map(e => ({
            source: e.source,
            severity: e.severity,
            message: e.message,
            blocking: e.blocking,
        }));
    }
    if (result.auditWarnings && result.auditWarnings.length > 0) {
        evidence.auditWarnings = result.auditWarnings.map(w => ({
            name: w.name,
            severity: w.severity,
            title: w.title,
            url: w.url,
            fixAvailable: w.fixAvailable,
        }));
    }
    const filePath = join(tasksDir, `${taskId}-VERIFY.json`);
    writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
}
// ─── Markdown Evidence Table ─────────────────────────────────────────────────
/**
 * Format duration in milliseconds as seconds with 1 decimal place.
 * e.g. 2340 → "2.3s", 150 → "0.2s", 0 → "0.0s"
 *
 * Distinct from the shared formatDuration (which uses adaptive ms/s/m/h units);
 * evidence tables always display seconds for consistent column alignment.
 */
function formatDurationSecs(ms) {
    return `${(ms / 1000).toFixed(1)}s`;
}
/**
 * Generate a markdown evidence table from a VerificationResult.
 *
 * Returns a "no checks" note if result.checks is empty.
 * Otherwise returns a 5-column markdown table: #, Command, Exit Code, Verdict, Duration.
 */
export function formatEvidenceTable(result) {
    if (result.checks.length === 0) {
        return "_No verification checks discovered._";
    }
    const lines = [
        "| # | Command | Exit Code | Verdict | Duration |",
        "|---|---------|-----------|---------|----------|",
    ];
    for (let i = 0; i < result.checks.length; i++) {
        const check = result.checks[i];
        const num = i + 1;
        const verdict = check.exitCode === 0 ? "✅ pass" : "❌ fail";
        const duration = formatDurationSecs(check.durationMs);
        lines.push(`| ${num} | ${check.command} | ${check.exitCode} | ${verdict} | ${duration} |`);
    }
    if (result.runtimeErrors && result.runtimeErrors.length > 0) {
        lines.push("");
        lines.push("**Runtime Errors**");
        lines.push("");
        lines.push("| # | Source | Severity | Blocking | Message |");
        lines.push("|---|--------|----------|----------|---------|");
        for (let i = 0; i < result.runtimeErrors.length; i++) {
            const err = result.runtimeErrors[i];
            const blockIcon = err.blocking ? "🚫 yes" : "ℹ️ no";
            lines.push(`| ${i + 1} | ${err.source} | ${err.severity} | ${blockIcon} | ${err.message.slice(0, 100)} |`);
        }
    }
    if (result.auditWarnings && result.auditWarnings.length > 0) {
        const severityEmoji = {
            critical: "🔴",
            high: "🟠",
            moderate: "🟡",
            low: "⚪",
        };
        lines.push("");
        lines.push("**Audit Warnings**");
        lines.push("");
        lines.push("| # | Package | Severity | Title | Fix Available |");
        lines.push("|---|---------|----------|-------|---------------|");
        for (let i = 0; i < result.auditWarnings.length; i++) {
            const w = result.auditWarnings[i];
            const emoji = severityEmoji[w.severity] ?? "⚪";
            const fix = w.fixAvailable ? "✅ yes" : "❌ no";
            lines.push(`| ${i + 1} | ${w.name} | ${emoji} ${w.severity} | ${w.title} | ${fix} |`);
        }
    }
    return lines.join("\n");
}
