"""Parser for OpenAI Codex CLI conversation data.

Codex stores sessions in ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<id>.jsonl
Each file has:
- session_meta: contains cwd (project path)
- response_item: contains payload with role (user/assistant/developer)

We filter out:
- developer role messages (system injected)
- user role messages that start with "#" or "<" (AGENTS.md / permissions)
"""
import json
from pathlib import Path


def _is_real_user_prompt(payload: dict) -> bool:
    """Check if a response_item payload is a genuine user prompt.

    Filters out system-injected messages:
    - developer role
    - user messages starting with '<' (permissions XML)
    - user messages starting with '#' (AGENTS.md instructions)
    """
    if payload.get("role") != "user":
        return False
    content = payload.get("content", [])
    for item in content:
        text = item.get("text", "")
        stripped = text.strip()
        if stripped.startswith("<") or stripped.startswith("#"):
            return False
    return True


def _parse_session_file(path: Path) -> dict:
    """Parse a single Codex session file.

    Returns: {"cwd": str, "prompts": int, "first_prompt": str,
              "session_id": str, "timestamp": str, "user_prompts": [str]}
    """
    cwd = None
    prompts = 0
    first_prompt = ""
    session_id = ""
    timestamp = ""
    user_prompts = []

    with open(path) as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            try:
                entry = json.loads(line)
            except json.JSONDecodeError:
                continue

            if entry.get("type") == "session_meta":
                payload = entry.get("payload", {})
                cwd = payload.get("cwd")
                session_id = payload.get("id", "")
                timestamp = entry.get("timestamp", "")
            elif entry.get("type") == "response_item":
                payload = entry.get("payload", {})
                if _is_real_user_prompt(payload):
                    prompts += 1
                    text = ""
                    for item in payload.get("content", []):
                        text = item.get("text", "")
                        if text:
                            break
                    user_prompts.append(text)
                    if not first_prompt:
                        first_prompt = text

    return {
        "cwd": cwd, "prompts": prompts, "first_prompt": first_prompt,
        "session_id": session_id, "timestamp": timestamp,
        "user_prompts": user_prompts,
    }


def count_for_project(project_path: str, codex_dir: Path) -> dict:
    """Count prompts for a project across all Codex session files.

    Scans all rollout-*.jsonl files, matches by cwd.
    Returns: {"prompts": N, "sessions": M}
    """
    sessions_dir = codex_dir / "sessions"
    if not sessions_dir.exists():
        return {"prompts": 0, "sessions": 0}

    total_prompts = 0
    total_sessions = 0

    for session_file in sessions_dir.rglob("rollout-*.jsonl"):
        result = _parse_session_file(session_file)
        if result["cwd"] == project_path and result["prompts"] > 0:
            total_prompts += result["prompts"]
            total_sessions += 1

    return {"prompts": total_prompts, "sessions": total_sessions}


def list_chats(project_path: str, codex_dir: Path) -> list[dict]:
    """List all chat sessions for a project, sorted by most recent first.

    Returns list of: {"first_prompt": str, "prompts": int, "timestamp": str,
                      "session_id": str, "tool": "codex"}
    """
    sessions_dir = codex_dir / "sessions"
    if not sessions_dir.exists():
        return []

    chats = []
    for session_file in sessions_dir.rglob("rollout-*.jsonl"):
        result = _parse_session_file(session_file)
        if result["cwd"] == project_path and result["prompts"] > 0:
            chats.append({
                "first_prompt": result["first_prompt"],
                "prompts": result["prompts"],
                "timestamp": result["timestamp"],
                "session_id": result["session_id"],
                "tool": "codex",
            })

    chats.sort(key=lambda c: c.get("timestamp", ""), reverse=True)
    return chats
