from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def audit_path(home: Path | None, config: dict[str, Any] | None = None) -> Path:
    cfg = (config or {}).get("mcp", {})
    rel = cfg.get("audit_file", "mcp/audit.jsonl")
    base = home or Path.cwd()
    return (base / rel).resolve()


def write_audit(
    *,
    home: Path | None,
    config: dict[str, Any] | None,
    direction: str,
    tool: str,
    args_summary: str = "",
    ok: bool = True,
    duration_ms: int = 0,
    client_id: str | None = None,
    capability_id: str | None = None,
    error: str | None = None,
) -> None:
    path = audit_path(home, config)
    path.parent.mkdir(parents=True, exist_ok=True)
    row = {
        "ts": datetime.now(timezone.utc).isoformat(),
        "direction": direction,
        "client_id": client_id or "local",
        "tool": tool,
        "args_summary": args_summary[:200],
        "ok": ok,
        "duration_ms": duration_ms,
    }
    if capability_id:
        row["capability_id"] = capability_id
    if error:
        row["error"] = error[:500]
    with path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(row, ensure_ascii=False) + "\n")


def read_mcp_audit(
    home: Path | None,
    config: dict[str, Any] | None = None,
    *,
    since: str = "",
    direction: str = "",
    tool: str = "",
    capability_id: str = "",
    limit: int = 100,
) -> list[dict[str, Any]]:
    path = audit_path(home, config)
    since_val = str(since or "").strip()
    direction_val = str(direction or "").strip().lower()
    tool_val = str(tool or "").strip()
    cap_val = str(capability_id or "").strip()
    cap = max(1, min(int(limit or 100), 1000))
    entries: list[dict[str, Any]] = []
    if not path.is_file():
        return entries
    for line in path.read_text(encoding="utf-8").strip().split("\n"):
        if not line:
            continue
        try:
            row = json.loads(line)
        except json.JSONDecodeError:
            continue
        if since_val:
            ts = str(row.get("ts") or "")
            if ts and ts < since_val:
                continue
        if direction_val and str(row.get("direction") or "").lower() != direction_val:
            continue
        if tool_val and str(row.get("tool") or "") != tool_val:
            continue
        if cap_val and str(row.get("capability_id") or "") != cap_val:
            continue
        entries.append(row)
    if len(entries) > cap:
        entries = entries[-cap:]
    return entries
