"""Test utilities for capturing stdlib log records."""

from __future__ import annotations

import logging
from collections.abc import Generator
from contextlib import contextmanager
from typing import Any


class _CaptureHandler(logging.Handler):
    """Handler that stores every emitted record as a dict."""

    def __init__(self) -> None:
        super().__init__()
        self.records: list[dict[str, Any]] = []

    def emit(self, record: logging.LogRecord) -> None:
        entry: dict[str, Any] = {
            "event": record.getMessage(),
            "level": record.levelname.lower(),
            "logger": record.name,
        }
        # Merge extra fields attached to the record.
        std_attrs = {
            "name",
            "msg",
            "args",
            "levelname",
            "levelno",
            "pathname",
            "filename",
            "module",
            "exc_info",
            "exc_text",
            "stack_info",
            "lineno",
            "funcName",
            "created",
            "msecs",
            "relativeCreated",
            "thread",
            "threadName",
            "processName",
            "process",
            "message",
            "asctime",
            "taskName",
        }
        for key, value in record.__dict__.items():
            if key not in std_attrs:
                entry[key] = value
        self.records.append(entry)


@contextmanager
def capture_logs() -> Generator[list[dict[str, Any]], None, None]:
    """Capture all log records emitted inside the context.

    Yields a list of dicts, each representing a log entry with keys
    ``event``, ``level``, ``logger`` and any extra fields.
    """
    handler = _CaptureHandler()
    handler.setLevel(logging.DEBUG)
    root = logging.getLogger()
    root.addHandler(handler)
    try:
        yield handler.records
    finally:
        root.removeHandler(handler)
