// `keiko verify` — the real verification gate (NOT a dry-run). It detects the workspace, builds a
// plan from the detected npm scripts, runs the allowlisted commands through the #6 safe tool layer
// under per-command resource limits, and prints a redacted human table (or --json of the report).
// Exit 0 when overall status is `passed`; 1 when any step did not pass or a workspace/runtime error
// occurred; 2 on a usage error. Mirrors runContextCli's structure (flag parsing, --json, typed
// error catch at the boundary).
import { detectWorkspace, WorkspaceError } from "@oscharko-dev/keiko-workspace";
import { buildVerificationPlan, buildVerificationSummary, detectScripts, EmptyPlanError, runVerification, VerificationError, } from "@oscharko-dev/keiko-verification";
const VALID_KINDS = new Set([
    "test",
    "targeted-test",
    "typecheck",
    "lint",
    "build",
]);
const USAGE = `Usage:
  keiko verify [--dir PATH] [--only KIND[,KIND]] [--changed FILE[,FILE]] [--json]

Runs the project's own gates (typecheck, lint, test, build) through the safe tool
layer under per-command resource limits and prints a redacted evidence summary.
KIND is one of: test, targeted-test, typecheck, lint, build.
`;
// Returns the value of a `--flag value` pair, undefined if absent, or null if present without a
// value (a usage error) — identical contract to runContextCli's flagValue.
function flagValue(args, name) {
    const i = args.indexOf(name);
    if (i === -1) {
        return undefined;
    }
    const value = args[i + 1];
    return value === undefined || value.startsWith("--") ? null : value;
}
function parseKinds(raw) {
    const parts = raw.split(",").map((p) => p.trim());
    if (parts.some((p) => !VALID_KINDS.has(p))) {
        return null;
    }
    return parts;
}
function parseArgs(args) {
    const dirRaw = flagValue(args, "--dir");
    const onlyRaw = flagValue(args, "--only");
    const changedRaw = flagValue(args, "--changed");
    if (dirRaw === null || onlyRaw === null || changedRaw === null) {
        return null;
    }
    const only = onlyRaw === undefined ? undefined : parseKinds(onlyRaw);
    if (only === null) {
        return null;
    }
    const changed = changedRaw === undefined ? undefined : changedRaw.split(",").map((p) => p.trim());
    return { dir: dirRaw ?? ".", only, changed, json: args.includes("--json") };
}
async function runPlan(parsed) {
    const workspace = detectWorkspace(parsed.dir);
    const catalog = detectScripts(workspace);
    const plan = buildVerificationPlan(workspace, catalog, {
        only: parsed.only,
        changedFiles: parsed.changed,
    });
    if (plan.steps.length === 0) {
        throw new EmptyPlanError("verification plan contains no runnable or skipped steps");
    }
    return runVerification(plan, { workspace });
}
function renderText(report, io) {
    const summary = buildVerificationSummary(report);
    io.out(`Verification: ${summary.overallStatus} (${String(summary.durationMs)}ms)\n`);
    io.out("KIND\tSTATUS\tEXIT\tMS\tCOMMAND\tDETAIL\n");
    for (const r of summary.results) {
        const exit = r.exitCode === null ? "-" : String(r.exitCode);
        io.out(`${r.kind}\t${r.status}\t${exit}\t${String(r.durationMs)}\t${r.command}\t${r.detail ?? ""}\n`);
    }
}
export async function runVerifyCli(args, io) {
    // Issue #640: handle --help / -h before workflow-arg validation so help discovery exits 0
    // with usage on stdout, not 2 with a validation error on stderr.
    if (args.includes("--help") || args.includes("-h")) {
        io.out(USAGE);
        return 0;
    }
    const parsed = parseArgs(args);
    if (parsed === null) {
        io.err(USAGE);
        return 2;
    }
    try {
        const report = await runPlan(parsed);
        if (parsed.json) {
            io.out(`${JSON.stringify(buildVerificationSummary(report), null, 2)}\n`);
        }
        else {
            renderText(report, io);
        }
        return report.overallStatus === "passed" ? 0 : 1;
    }
    catch (error) {
        if (error instanceof WorkspaceError) {
            io.err(`Error [${error.code}]: ${error.message}\n`);
            return 1;
        }
        if (error instanceof VerificationError) {
            io.err(`Error [${error.code}]: ${error.message}\n`);
            return 1;
        }
        throw error;
    }
}
