"""Command line:

    python -m router plan evals.csv --target 0.9 --delta 0.05 [--cal 0.5] [--seed 1] [--signal auto|confidence|learned]
                                    [--unit $] [--json out.json]
    python -m router sample          # print the two accepted CSV layouts
"""
from __future__ import annotations

import argparse
import json
import sys
import time

from .data import SAMPLE_LONG, SAMPLE_WIDE, load_csv
from .plan import plan
from .report import text_report


def main(argv=None):
    ap = argparse.ArgumentParser(prog="python -m router", description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    sub = ap.add_subparsers(dest="cmd", required=True)
    p = sub.add_parser("plan", help="choose and certify a routing policy from an eval log")
    p.add_argument("csv")
    p.add_argument("--target", type=float, default=0.9, help="quality target in [0, 1] (default 0.9)")
    p.add_argument("--delta", type=float, default=0.05, help="failure probability of the guarantee (default 0.05 = 95%% confidence)")
    p.add_argument("--cal", type=float, default=0.5, help="share of prompts used to tune thresholds (default 0.5); the rest certify")
    p.add_argument("--seed", type=int, default=1)
    p.add_argument("--signal", choices=["auto", "confidence", "learned"], default="auto",
                   help="gate the cascade on the reported confidence or on a router learned from prompt text")
    p.add_argument("--safety", type=float, default=1.0,
                   help="extra margin when tuning, in calibration standard errors (default 1); 0 tunes exactly to the certifiable rate")
    p.add_argument("--step", type=float, default=0.01, help="target spacing of the sensitivity sweep")
    p.add_argument("--unit", default="$", help="cost unit label for the report (default $)")
    p.add_argument("--json", help="also write the full report as JSON")
    sub.add_parser("sample", help="print the accepted CSV layouts")
    a = ap.parse_args(argv)
    if a.cmd == "sample":
        print("# wide: one row per prompt\n" + SAMPLE_WIDE + "\n# long: one row per prompt x model\n" + SAMPLE_LONG)
        return 0
    if not 0 < a.target <= 1 or not 0 < a.delta < 1 or not 0.05 <= a.cal <= 0.95:
        print("target must be in (0, 1], delta in (0, 1), cal in [0.05, 0.95]", file=sys.stderr)
        return 2
    t0 = time.perf_counter()
    log = load_csv(a.csv)
    rep = plan(log, target=a.target, delta=a.delta, cal_frac=a.cal, seed=a.seed, signal=a.signal, step=a.step, safety=a.safety)
    rep["seconds"] = time.perf_counter() - t0
    print(text_report(rep, a.unit))
    if a.json:
        with open(a.json, "w", encoding="utf-8") as f:
            json.dump(rep, f, indent=1)
        print(f"\nwrote {a.json}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
