"""
cortex/api/routes/debug.py — Debug log API routes.

Provides endpoints for querying debug logs, viewing stats,
streaming live logs (SSE), and clearing the buffer.

These are diagnostic endpoints — not for production traffic.
"""

from __future__ import annotations

import asyncio
import json
import logging
import time
from typing import Any, Optional

logger = logging.getLogger(__name__)

try:
    from fastapi import APIRouter, Depends, Query
    from fastapi.responses import JSONResponse, StreamingResponse
    _FASTAPI_AVAILABLE = True
except ImportError:
    _FASTAPI_AVAILABLE = False

router = APIRouter() if _FASTAPI_AVAILABLE else None  # type: ignore

# SSE connection tracking — cap concurrent debug streams (#482)
_active_streams: int = 0
_MAX_STREAMS: int = 5


def _make_routes(verify_api_key: Any) -> None:
    """Register debug routes on the module-level router."""
    if not _FASTAPI_AVAILABLE:
        return

    @router.get("/api/v1/debug/logs", dependencies=[Depends(verify_api_key)])
    async def get_debug_logs(
        last: int = Query(50, ge=1, le=10000),
        session_id: Optional[str] = Query(None),
        endpoint: Optional[str] = Query(None),
        min_latency_ms: Optional[float] = Query(None),
        event_type: Optional[str] = Query(None),
    ) -> JSONResponse:
        """Query debug log entries with optional filters."""
        from cortex.debug import is_debug_enabled, get_debug_buffer

        if not is_debug_enabled():
            return JSONResponse(
                status_code=200,
                content={"enabled": False, "entries": [], "message": "Debug logging is disabled"},
            )

        buf = get_debug_buffer()
        entries = buf.query(
            last=last,
            session_id=session_id,
            endpoint=endpoint,
            min_latency_ms=min_latency_ms,
            event_type=event_type,
        )
        return JSONResponse(
            status_code=200,
            content={"enabled": True, "count": len(entries), "entries": entries},
        )

    @router.get("/api/v1/debug/logs/stream", dependencies=[Depends(verify_api_key)])
    async def stream_debug_logs(
        session_id: Optional[str] = Query(None),
        endpoint: Optional[str] = Query(None),
        timeout: int = Query(300, ge=1, le=3600, description="Stream timeout in seconds"),
    ) -> StreamingResponse:
        """SSE stream for live-tailing debug logs.

        Limited to _MAX_STREAMS concurrent connections. Returns 429 when limit
        is reached. Disconnects automatically after ``timeout`` seconds (default 300).
        """
        global _active_streams

        # Connection limit guard (#482)
        if _active_streams >= _MAX_STREAMS:
            from fastapi.responses import JSONResponse as _JSONResponse
            return _JSONResponse(  # type: ignore[return-value]
                status_code=429,
                content={
                    "error": "too_many_streams",
                    "message": f"Maximum concurrent debug streams ({_MAX_STREAMS}) reached. Try again later.",
                    "active": _active_streams,
                    "max": _MAX_STREAMS,
                },
            )

        from cortex.debug import is_debug_enabled, get_debug_buffer

        async def event_generator():
            global _active_streams
            _active_streams += 1
            deadline = time.monotonic() + timeout
            try:
                buf = get_debug_buffer()
                seen = len(buf)
                yield "data: {\"connected\": true}\n\n"

                while True:
                    # Timeout guard — disconnect after configured duration
                    if time.monotonic() >= deadline:
                        yield "data: {\"disconnected\": true, \"reason\": \"timeout\"}\n\n"
                        break

                    if not is_debug_enabled():
                        yield "data: {\"paused\": true, \"reason\": \"debug_logging_disabled\"}\n\n"
                        await asyncio.sleep(5)
                        continue

                    current_len = len(buf)
                    if current_len > seen:
                        new_entries = buf.query(last=current_len - seen)
                        for entry in reversed(new_entries):
                            if session_id and entry.get("session_id") != session_id:
                                continue
                            if endpoint and not entry.get("path", "").startswith(endpoint):
                                continue
                            yield f"data: {json.dumps(entry)}\n\n"
                        seen = current_len

                    await asyncio.sleep(0.5)
            finally:
                _active_streams -= 1

        return StreamingResponse(
            event_generator(),
            media_type="text/event-stream",
            headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
        )

    @router.get("/api/v1/debug/stats", dependencies=[Depends(verify_api_key)])
    async def get_debug_stats() -> JSONResponse:
        """Get summary statistics from the debug log buffer."""
        from cortex.debug import is_debug_enabled, get_debug_buffer

        if not is_debug_enabled():
            return JSONResponse(
                status_code=200,
                content={"enabled": False, "message": "Debug logging is disabled"},
            )

        buf = get_debug_buffer()
        stats = buf.stats()
        stats["enabled"] = True
        return JSONResponse(status_code=200, content=stats)

    @router.delete("/api/v1/debug/logs", dependencies=[Depends(verify_api_key)])
    async def clear_debug_logs() -> JSONResponse:
        """Clear all entries from the debug log buffer."""
        from cortex.debug import get_debug_buffer

        buf = get_debug_buffer()
        cleared = buf.clear()
        logger.info(
            "AUDIT debug_clear: cleared=%d entries timestamp=%s",
            cleared,
            time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        )
        return JSONResponse(
            status_code=200,
            content={"cleared": cleared, "message": f"Cleared {cleared} debug log entries"},
        )
