"""Sprint context analysis — parse Claude tool logs, detect waste, generate JSON reports."""

import json
from collections import Counter
from pathlib import Path

TOKENS_PER_LINE = 4
DEFAULT_FULL_FILE_LINES = 500


def parse_read_log(path: Path) -> list[dict]:
    if not path.exists():
        return []
    entries = []
    for line in path.read_text().splitlines():
        line = line.strip()
        if not line:
            continue
        try:
            entries.append(json.loads(line))
        except json.JSONDecodeError:
            continue
    return entries


def analyze_reads(entries: list[dict]) -> dict:
    read_entries = [e for e in entries if e.get("tool", "Read") == "Read"]
    if not read_entries:
        return {
            "total_reads": 0,
            "unique_files": 0,
            "reread_count": 0,
            "reread_ratio": 0.0,
            "estimated_tokens": 0,
            "top_files": [],
            "wasteful_reads": [],
        }

    file_counts = Counter(e["file"] for e in read_entries)
    total_lines = sum(e.get("limit", 0) or DEFAULT_FULL_FILE_LINES for e in read_entries)

    seen: dict[str, dict] = {}
    wasteful: list[dict] = []
    reread_count = 0
    for entry in read_entries:
        key = entry["file"]
        if key in seen:
            reread_count += 1
            prev = seen[key]
            if entry.get("offset") == prev.get("offset") and entry.get("limit") == prev.get("limit"):
                wasteful.append(
                    {
                        "file": key,
                        "count": file_counts[key],
                        "range": f"{entry.get('offset', 0)}-{entry.get('limit', 0)}",
                    }
                )
        seen[key] = entry

    wasteful_deduped = {w["file"]: w for w in wasteful}
    top_files = [{"file": f, "count": c} for f, c in file_counts.most_common(10)]

    return {
        "total_reads": len(read_entries),
        "unique_files": len(file_counts),
        "reread_count": reread_count,
        "reread_ratio": round(reread_count / len(read_entries), 2),
        "estimated_tokens": total_lines * TOKENS_PER_LINE,
        "top_files": top_files,
        "wasteful_reads": list(wasteful_deduped.values()),
    }


def analyze_tool_usage(entries: list[dict]) -> dict:
    tool_counts = Counter(e.get("tool", "Read") for e in entries)
    read_tools = {"Read", "Grep", "Glob"}
    write_tools = {"Edit", "Write"}
    reads = sum(tool_counts.get(t, 0) for t in read_tools)
    writes = sum(tool_counts.get(t, 0) for t in write_tools)
    return {
        "total_tool_calls": len(entries),
        "by_tool": dict(tool_counts.most_common()),
        "reads": reads,
        "writes": writes,
        "read_write_ratio": round(reads / writes, 2) if writes > 0 else None,
    }


def analyze_efficiency(entries: list[dict]) -> dict:
    read_entries = [e for e in entries if e.get("tool") == "Read"]
    seen_files: dict[str, int] = {}
    reread_count = 0
    exact_reread_count = 0
    for e in read_entries:
        key = e.get("file", "")
        if not key:
            continue
        if key in seen_files:
            reread_count += 1
            prev_offset = seen_files.get(f"{key}_offset")
            prev_limit = seen_files.get(f"{key}_limit")
            if e.get("offset", 0) == prev_offset and e.get("limit", 0) == prev_limit:
                exact_reread_count += 1
        seen_files[key] = seen_files.get(key, 0) + 1
        seen_files[f"{key}_offset"] = e.get("offset", 0) or 0
        seen_files[f"{key}_limit"] = e.get("limit", 0) or 0

    grep_entries = [e for e in entries if e.get("tool") == "Grep"]
    grep_patterns = [e.get("pattern", "") for e in grep_entries]
    unique_patterns = len(set(grep_patterns))

    return {
        "total_reads": len(read_entries),
        "reread_count": reread_count,
        "exact_reread_count": exact_reread_count,
        "reread_waste_ratio": round(exact_reread_count / len(read_entries), 2) if read_entries else 0.0,
        "unique_grep_patterns": unique_patterns,
        "total_grep_calls": len(grep_entries),
    }


def analyze_errors(entries: list[dict]) -> dict:
    error_entries = [e for e in entries if e.get("error") is True]
    total = len(entries)
    total_errors = len(error_entries)

    errors_by_tool: dict[str, int] = {}
    for e in error_entries:
        tool = e.get("tool", "unknown")
        errors_by_tool[tool] = errors_by_tool.get(tool, 0) + 1

    bash_error_cmds = [e.get("command", "") for e in error_entries if e.get("tool") == "Bash" and e.get("command")]
    cmd_counts = Counter(bash_error_cmds)
    top_error_commands = [{"command": cmd, "count": cnt} for cmd, cnt in cmd_counts.most_common(5)]

    return {
        "total_errors": total_errors,
        "error_rate": round(total_errors / total, 2) if total > 0 else 0.0,
        "errors_by_tool": errors_by_tool,
        "top_error_commands": top_error_commands,
    }


def skill_usage_stats(entries: list[dict]) -> dict[str, int]:
    counts: dict[str, int] = {}
    for e in entries:
        if e.get("tool") == "Skill":
            skill = e.get("skill", "unknown")
            counts[skill] = counts.get(skill, 0) + 1
    return dict(sorted(counts.items(), key=lambda x: -x[1]))


def generate_sprint_report(log_dir: Path, output_dir: Path, sprint: int) -> Path:
    all_entries: list[dict] = []
    sessions: list[dict] = []

    for log_file in sorted(log_dir.glob("tools-*.jsonl")):
        entries = parse_read_log(log_file)
        if entries:
            session_metrics = analyze_reads(entries)
            session_metrics["session_id"] = log_file.stem.replace("tools-", "")
            session_metrics["tool_usage"] = analyze_tool_usage(entries)
            session_metrics["efficiency"] = analyze_efficiency(entries)
            session_metrics["errors"] = analyze_errors(entries)
            sessions.append(session_metrics)
            all_entries.extend(entries)

    # Fallback: also check legacy reads-*.jsonl files
    for log_file in sorted(log_dir.glob("reads-*.jsonl")):
        entries = parse_read_log(log_file)
        if entries:
            session_metrics = analyze_reads(entries)
            session_metrics["session_id"] = log_file.stem.replace("reads-", "")
            session_metrics["tool_usage"] = analyze_tool_usage(entries)
            session_metrics["efficiency"] = analyze_efficiency(entries)
            session_metrics["errors"] = analyze_errors(entries)
            sessions.append(session_metrics)
            all_entries.extend(entries)

    aggregate = analyze_reads(all_entries)
    aggregate["tool_usage"] = analyze_tool_usage(all_entries)
    aggregate["efficiency"] = analyze_efficiency(all_entries)
    aggregate["errors"] = analyze_errors(all_entries)
    report = {
        "sprint": sprint,
        **aggregate,
        "sessions": sessions,
    }

    output_dir.mkdir(parents=True, exist_ok=True)
    report_path = output_dir / f"SPRINT{sprint}_CONTEXT_REPORT.json"
    report_path.write_text(json.dumps(report, indent=2) + "\n")
    return report_path
