"""Structured logging setup with file rotation and JSON format.

Provides:
- Console handler (human-readable) for stderr
- Rotating file handler (JSON structured) for ~/.agntspace/logs/
- Per-service log level configuration
- Never logs vault content or PII
"""

from __future__ import annotations

import json
import logging
import logging.handlers
import sys
import traceback
from datetime import UTC, datetime
from pathlib import Path


class JSONFormatter(logging.Formatter):
    """Structured JSON log formatter for file output."""

    def format(self, record: logging.LogRecord) -> str:
        entry: dict = {
            "ts": datetime.fromtimestamp(record.created, tz=UTC).isoformat(),
            "level": record.levelname,
            "logger": record.name,
            "msg": record.getMessage(),
        }
        if record.exc_info and record.exc_info[1]:
            entry["error"] = {
                "type": type(record.exc_info[1]).__name__,
                "message": str(record.exc_info[1]),
                "traceback": traceback.format_exception(*record.exc_info),
            }
        # Extra fields from LoggerAdapter or extra={}
        for key in ("request_id", "method", "path", "status_code", "duration_ms",
                     "service", "action", "user_agent"):
            val = getattr(record, key, None)
            if val is not None:
                entry[key] = val
        return json.dumps(entry, default=str)


def setup_logging(level: str = "WARNING", log_dir: Path | None = None) -> None:
    """Configure application logging.

    Args:
        level: Default log level for console output.
        log_dir: Directory for log files. If provided, adds a rotating
                 file handler with JSON-structured output at DEBUG level.
    """
    root = logging.getLogger("agntspace")
    # Prevent duplicate handlers on re-init
    if root.handlers:
        return
    root.setLevel(logging.DEBUG)  # Let handlers decide their own level

    # ── Console handler (human-readable, respects level arg) ──
    console = logging.StreamHandler(sys.stderr)
    console.setLevel(getattr(logging, level.upper(), logging.WARNING))
    console.setFormatter(logging.Formatter(
        fmt="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    ))
    root.addHandler(console)

    # ── File handler (JSON structured, DEBUG level, with rotation) ──
    if log_dir:
        log_dir.mkdir(parents=True, exist_ok=True)
        log_file = log_dir / "agntspace.log"
        file_handler = logging.handlers.RotatingFileHandler(
            str(log_file),
            maxBytes=10 * 1024 * 1024,  # 10 MB
            backupCount=5,
            encoding="utf-8",
        )
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(JSONFormatter())
        root.addHandler(file_handler)

        # Separate error-only file for quick triage
        error_file = log_dir / "errors.log"
        error_handler = logging.handlers.RotatingFileHandler(
            str(error_file),
            maxBytes=5 * 1024 * 1024,  # 5 MB
            backupCount=3,
            encoding="utf-8",
        )
        error_handler.setLevel(logging.ERROR)
        error_handler.setFormatter(JSONFormatter())
        root.addHandler(error_handler)

    # Suppress noisy library loggers
    for name in ("httpx", "httpcore", "uvicorn.access", "litellm",
                 "watchfiles", "aiosqlite"):
        logging.getLogger(name).setLevel(logging.WARNING)
