from __future__ import annotations
import argparse
import sys
from pathlib import Path

from .runner import run_case
from .tester import iter_case_dirs, run_one_case


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(prog="toughanimator")
    sub = p.add_subparsers(dest="cmd", required=True)

    p_run = sub.add_parser("run", help="Run toughanimator on a single case directory")
    p_run.add_argument("case_dir", help="Path to case folder (contains config.json/MESH/INCON/...)")
    p_run.add_argument(
        "--mode",
        default="all",
        choices=["all", "eleme_conne", "geometry", "incon", "result"],
        help="What to generate",
    )

    p_test = sub.add_parser("test", help="Run regression tests on many cases (writes results back into each case).")
    p_test.add_argument("cases_root", help="Root directory containing case folders (each with config.json).")
    p_test.add_argument("--stage", default="convert", choices=["parse", "convert", "sanity"])
    p_test.add_argument("--mode", default="all", choices=["all", "eleme_conne", "geometry", "incon", "result"])
    p_test.add_argument("--fail-fast", action="store_true", help="Stop at first failure.")
    p_test.add_argument("--case", dest="cases", action="append", default=[], help="Run only this case dir (repeatable).")

    return p


def main(argv: list[str] | None = None) -> int:
    args = build_parser().parse_args(argv)

    if args.cmd == "run":
        res = run_case(args.case_dir, mode=args.mode)
        if res.ok:
            print(f"[OK] {res.case_dir}")
            return 0
        else:
            print(f"[FAIL] {res.case_dir}\n{res.error}", file=sys.stderr)
            return 2

    if args.cmd == "test":
        root = Path(args.cases_root).expanduser().resolve()
        case_dirs = [Path(p).expanduser().resolve() for p in args.cases] if args.cases else iter_case_dirs(root)

        n_pass = n_fail = 0
        for c in case_dirs:
            tr = run_one_case(c, stage=args.stage, mode=args.mode, repo_root=Path.cwd())
            print(f"[{tr.status.upper():4}] {c} ({tr.duration_sec:.2f}s)")
            if tr.status == "pass":
                n_pass += 1
            else:
                n_fail += 1
                if args.fail_fast:
                    break

        print(f"\nSummary: pass={n_pass} fail={n_fail} total={n_pass+n_fail}")
        return 0 if n_fail == 0 else 2

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
