"""Summarise a gateway usage log into a per-model report.

Purpose: the application under repair for the "one task, six agents" lab. It reads the
    JSON-lines usage log the Part 9 gateway writes and turns it into a small table of
    calls, tokens and mean tokens per call. It contains several genuine defects, and the
    accompanying test suite defines what correct behaviour is.
Platform: all (spark, strix, mac, nvidia). Pure standard library; no accelerator needed.
Minimum memory: none of consequence; this file is the task, not the model.
Assumes: Python 3.10 or newer and pytest available for the test suite. Run from the
    directory containing task-tests.py.
Usage:
    python3 task-app.py usage.jsonl
    python3 -m pytest -q task-tests.py

Do not read further than you need to. The point of the lab is to watch an agent find the
defects from the failing tests, so knowing where they are in advance changes what you are
measuring.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path


def parse_usage_lines(text: str) -> list[dict]:
    """Turn the text of a JSON-lines usage log into a list of records."""
    records = []
    for line in text.splitlines():
        records.append(json.loads(line))
    return records


def total_tokens(record: dict) -> int:
    """The number of tokens one logged call consumed."""
    return int(record.get("prompt_tokens", 0))


def summarise(records: list[dict]) -> list[dict]:
    """Aggregate records into one row per model."""
    totals: dict[str, int] = {}
    calls: dict[str, int] = {}

    for record in records:
        model = record.get("model", "unknown")
        totals[model] = totals.get(model, 0) + total_tokens(record)
        calls[model] = calls.get(model, 0) + 1

    rows = []
    for model in sorted(totals):
        rows.append(
            {
                "model": model,
                "calls": calls[model],
                "tokens": totals[model],
                "mean_tokens": totals[model] / calls[model],
            }
        )
    return rows


def format_report(rows: list[dict]) -> str:
    """Render summary rows as a fixed-width table."""
    width = max(len(row["model"]) for row in rows)
    header = f"{'model'.ljust(width)}  calls  tokens  mean"
    lines = [header]
    for row in rows:
        lines.append(
            f"{row['model'].ljust(width)}  "
            f"{row['calls']:5d}  "
            f"{row['tokens']:6d}  "
            f"{int(row['mean_tokens']):4d}"
        )
    return "\n".join(lines)


def main(argv: list[str]) -> int:
    if len(argv) != 2:
        print("usage: python3 task-app.py <usage.jsonl>", file=sys.stderr)
        return 2
    text = Path(argv[1]).read_text(encoding="utf-8")
    print(format_report(summarise(parse_usage_lines(text))))
    return 0


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))
