from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_REPORT_DIR = ROOT / "reports" / "observability"


def iter_turn_audit(report_dir: Path) -> list[dict[str, Any]]:
    records: list[dict[str, Any]] = []
    if not report_dir.exists():
        return records
    for path in sorted(report_dir.rglob("turn_audit/*.jsonl")):
        with path.open("r", encoding="utf-8") as handle:
            for line_number, line in enumerate(handle, start=1):
                line = line.strip()
                if not line:
                    continue
                try:
                    record = json.loads(line)
                except json.JSONDecodeError as exc:
                    raise ValueError(f"{path}:{line_number}: invalid JSONL: {exc}") from exc
                if isinstance(record, dict):
                    records.append(record)
    return records


def filter_failed(records: list[dict[str, Any]], *, limit: int | None = None) -> list[dict[str, Any]]:
    failed = [
        {
            "timestamp": record.get("timestamp"),
            "turn_id": record.get("turn_id"),
            "plugin": record.get("plugin"),
            "project_id": record.get("project_id"),
            "chat_id": record.get("chat_id"),
            "request_id": record.get("request_id"),
            "outcome": record.get("outcome"),
            "failure_type": record.get("failure_type"),
            "error_code": record.get("error_code"),
            "error_message": record.get("error_message"),
            "user_text": record.get("user_text"),
        }
        for record in records
        if str(record.get("outcome") or "") != "success"
    ]
    failed.sort(key=lambda item: str(item.get("timestamp") or ""), reverse=True)
    if limit is not None:
        return failed[:limit]
    return failed


def write_report(path: Path, payload: dict[str, Any]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")


def main() -> int:
    parser = argparse.ArgumentParser(description="Report failed and partial turns from observability logs.")
    parser.add_argument("--report-dir", type=Path, default=DEFAULT_REPORT_DIR)
    parser.add_argument("--limit", type=int, default=50)
    parser.add_argument("--output", type=Path, help="Optional JSON output path.")
    args = parser.parse_args()

    records = iter_turn_audit(args.report_dir)
    failed = filter_failed(records, limit=args.limit)
    payload = {"records": len(records), "failed_turns": failed}
    print(json.dumps(payload, ensure_ascii=False, indent=2))
    if args.output:
        write_report(args.output, payload)
    return 0


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