#!/usr/bin/env python3
"""
Run mugi_testing tool scenarios (direct StructuredTool.invoke, no LLM).

Default: read_only tier only — safe for quick regression checks.

Usage (from repo root, with project venv):
  python scripts/tool_smoke.py
  python scripts/tool_smoke.py --dry-run
  python scripts/tool_smoke.py --tool read_file
  python scripts/tool_smoke.py --list
  python scripts/tool_smoke.py --tiers read_only,network   # plus MUGI_SMOKE_NETWORK=1 for read_webpage

Bridge scenarios need MUGI_SMOKE_BRIDGE=1 and a running Swift app with bridge + token.

See ``testing/deliberate_matrix.json`` (deterministic_tools layer) and ``scripts/run_deliberate_matrix.py``.
"""
from __future__ import annotations

import argparse
import os
import sys

_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
_PROJECT_ROOT = os.path.dirname(_SCRIPT_DIR)
if _PROJECT_ROOT not in sys.path:
    sys.path.insert(0, _PROJECT_ROOT)

from mugi_testing.tool_harness import run_scenarios, summarize  # noqa: E402
from mugi_testing.tool_scenarios import ALL_SCENARIOS, RiskTier, list_tool_names  # noqa: E402


def _parse_tiers(spec: str) -> set[RiskTier]:
    names = [x.strip().lower() for x in spec.split(",") if x.strip()]
    out: set[RiskTier] = set()
    for n in names:
        try:
            out.add(RiskTier(n))
        except ValueError:
            valid = ", ".join(t.value for t in RiskTier)
            raise SystemExit(f"Unknown tier {n!r}. Use one or more of: {valid}") from None
    return out


def main() -> int:
    p = argparse.ArgumentParser(description="Smoke-test tools via mugi_testing scenarios.")
    p.add_argument("--list", action="store_true", help="List registered (tool, scenario_id) pairs and exit.")
    p.add_argument("--list-tools", action="store_true", help="List distinct tool names in the registry and exit.")
    p.add_argument("--tool", type=str, default=None, help="Run only scenarios for this tool name.")
    p.add_argument(
        "--tiers",
        type=str,
        default=RiskTier.READ_ONLY.value,
        help=f"Comma-separated RiskTier values (default: {RiskTier.READ_ONLY.value}).",
    )
    p.add_argument("--dry-run", action="store_true", help="Resolve args only; do not invoke tools.")
    p.add_argument("--no-media", action="store_true", help="Pass include_media=False to get_tools().")
    p.add_argument("--cli", action="store_true", help="Include CLI tools in get_tools().")
    args = p.parse_args()

    if args.list_tools:
        for name in list_tool_names():
            print(name)
        return 0

    if args.list:
        for s in ALL_SCENARIOS:
            print(f"{s.tool_name}\t{s.scenario_id}\t{s.tier.value}\t{s.description}")
        return 0

    tier_set = _parse_tiers(args.tiers)
    results = run_scenarios(
        tiers=tier_set,
        tool_name=args.tool,
        dry_run=args.dry_run,
        include_media=not args.no_media,
        include_cli=args.cli,
    )

    if args.tool and not results:
        print(f"No scenarios for tool {args.tool!r} at requested tiers {args.tiers!r}. Try --list.", file=sys.stderr)
        return 2

    for r in results:
        status = "SKIP" if r.skipped else ("OK" if r.ok else "FAIL")
        extra = f" [{r.skip_reason}]" if r.skipped else ""
        print(f"{status}\t{r.tool_name}\t{r.scenario_id}\t{r.duration_sec:.3f}s{extra}")
        if r.message and (not r.ok or args.dry_run or r.skipped):
            for line in r.message.splitlines()[:12]:
                print(f"    {line}")

    passed, failed, skipped = summarize(results)
    print(f"\nSummary: {passed} passed, {failed} failed, {skipped} skipped")
    return 1 if failed else 0


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