# #region WsLogHandlerModule [C:3] [TYPE Module] [SEMANTICS pydantic, dto, log-entry]
# @BRIEF WebSocket log handler module providing LogEntry DTO and WebSocketLogHandler for buffered log streaming.
# @RELATION DEPENDS_ON -> [LogEntry]
# @RELATION DEPENDS_ON -> [CotJsonFormatter]
from collections import deque
from datetime import UTC, datetime
import logging
from typing import Any

from pydantic import BaseModel, Field


# #region LogEntry [C:1] [TYPE Class] [SEMANTICS log,entry,record,pydantic]
class LogEntry(BaseModel):
    timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))
    level: str
    message: str
    context: dict[str, Any] | None = None
# #endregion LogEntry


# #region WebSocketLogHandler [C:3] [TYPE Class] [SEMANTICS logging,handler,websocket,buffer]
# @BRIEF Custom logging handler that captures log records into a fixed-capacity buffer for WebSocket streaming.
# @RELATION DEPENDS_ON -> [LogEntry]
# @RELATION DEPENDS_ON -> [CotJsonFormatter]
class WebSocketLogHandler(logging.Handler):
    """
    A logging handler that stores log records and can be extended to send them
    over WebSockets.
    """

    # #region WebSocketLogHandler.__init__ [C:1] [TYPE Function] [SEMANTICS init,handler,buffer]
    def __init__(self, capacity: int = 1000):
        super().__init__()
        self.log_buffer: deque[LogEntry] = deque(maxlen=capacity)
    # #endregion WebSocketLogHandler.__init__

    # #region WebSocketLogHandler.emit [C:2] [TYPE Function] [SEMANTICS log,capture,format,buffer]
    # @BRIEF Captures a log record, formats it, and stores it in the buffer as a LogEntry.
    def emit(self, record: logging.LogRecord):
        try:
            log_entry = LogEntry(
                level=record.levelname,
                message=self.format(record),
                context={
                    "name": record.name,
                    "pathname": record.pathname,
                    "lineno": record.lineno,
                    "funcName": record.funcName,
                    "process": record.process,
                    "thread": record.thread,
                }
            )
            self.log_buffer.append(log_entry)
        except Exception:
            self.handleError(record)
    # #endregion WebSocketLogHandler.emit

    # #region WebSocketLogHandler.get_recent_logs [C:2] [TYPE Function] [SEMANTICS log,retrieve,buffer]
    # @BRIEF Returns a list of recent log entries from the buffer.
    def get_recent_logs(self) -> list[LogEntry]:
        """
        Returns a list of recent log entries from the buffer.
        """
        return list(self.log_buffer)
    # #endregion WebSocketLogHandler.get_recent_logs


# #endregion WebSocketLogHandler
# #endregion WsLogHandlerModule
