"""The core CLI is usable without ML dependencies, network access, or credentials."""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path


def parser() -> argparse.ArgumentParser:
    root = argparse.ArgumentParser(prog="hessian-recipes")
    root.add_argument("--version", action="version", version="hessian-recipes 0.1.0")
    commands = root.add_subparsers(dest="command", required=True)
    demo = commands.add_parser("demo", help="Replay the two synthetic development tracks offline")
    demo.add_argument("--workspace", type=Path, default=Path.cwd(), help="Path to repository clone")
    demo.add_argument("--output", type=Path, default=Path("runs/demo"))
    evaluation = commands.add_parser("eval", help="Run a frozen evaluation specification")
    evaluation.add_argument("spec", type=Path)
    evaluation.add_argument("--output", type=Path, required=True)
    compare = commands.add_parser("compare", help="Check coverage, compatibility, and regression")
    compare.add_argument("baseline", type=Path)
    compare.add_argument("candidate", type=Path)
    compare.add_argument("--max-drop", type=float, default=0.0)
    train = commands.add_parser("train", help="Run or inspect a pinned TRL training recipe")
    train.add_argument("config", type=Path)
    train.add_argument("--dry-run", action="store_true")
    distill = commands.add_parser("distill", help="Generate or verify offline teacher sequences")
    distill_commands = distill.add_subparsers(dest="distill_command", required=True)
    prepare = distill_commands.add_parser("prepare")
    prepare.add_argument("input", type=Path)
    prepare.add_argument("output", type=Path)
    generate = distill_commands.add_parser("generate")
    generate.add_argument("config", type=Path)
    trajectories = commands.add_parser("validate-trajectories", help="Validate a harness trace JSONL")
    trajectories.add_argument("input", type=Path)
    release = commands.add_parser("bundle", help="Assemble a local HF-style release candidate")
    release.add_argument("--output", type=Path, required=True)
    release.add_argument("--model-card", type=Path, required=True)
    release.add_argument("--report", type=Path, required=True)
    release.add_argument("--artifact", type=Path, action="append", required=True)
    release.add_argument("--training-manifest", type=Path)
    return root


def dispatch(args: argparse.Namespace) -> tuple[dict, int]:
    if args.command == "demo":
        from .evaluation import run

        reports = []
        for track in ("reasoning_reliability", "tool_workflow_reliability"):
            spec = args.workspace / "benchmarks" / track / "spec.json"
            if not spec.is_file():
                raise ValueError(f"Demo needs a repository clone; missing {spec}. Set --workspace.")
            result = run(spec, args.output / track)
            reports.append({"track": track, "status": result["status"], "metrics": result["metrics"]})
        summary = {"mode": "synthetic-development-replay", "release_eligible": False, "reports": reports}
        (args.output / "summary.json").write_text(json.dumps(summary, indent=2) + "\n", encoding="utf-8")
        return summary, 0 if all(r["status"] == "complete" for r in reports) else 1
    if args.command == "eval":
        from .evaluation import run

        result = run(args.spec, args.output)
        return result, 0 if result["status"] == "complete" else 1
    if args.command == "compare":
        from .evaluation import compare

        result = compare(args.baseline, args.candidate, max_drop=args.max_drop)
        return result, 0 if result["passed"] else 1
    if args.command == "train":
        from .training import plan, run

        return (plan(args.config) if args.dry_run else run(args.config)), 0
    if args.command == "distill":
        from .distillation import generate, prepare

        return (prepare(args.input, args.output) if args.distill_command == "prepare" else generate(args.config)), 0
    if args.command == "validate-trajectories":
        from .trajectories import read_trajectories

        records = read_trajectories(args.input)
        return {"valid": True, "episodes": len(records)}, 0
    if args.command == "bundle":
        from .releases import bundle

        return bundle(args.output, model_card=args.model_card, report=args.report,
                      artifacts=args.artifact, training_manifest=args.training_manifest), 0
    raise ValueError(f"Unknown command {args.command}")


def main(argv: list[str] | None = None) -> int:
    args = parser().parse_args(argv)
    try:
        result, code = dispatch(args)
    except (ValueError, OSError, ImportError, KeyError, TypeError, RuntimeError) as error:
        print(json.dumps({"error": str(error)}, ensure_ascii=False), file=sys.stderr)
        return 2
    print(json.dumps(result, indent=2, ensure_ascii=False, allow_nan=False))
    return code
