"""Structured logging setup using structlog."""

import logging
import sys
from functools import lru_cache

import structlog


def configure_logging(log_level: str = "INFO", log_json: bool = True) -> None:
    """Configure structlog with JSON or console output.

    Args:
        log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
        log_json: If True, output JSON logs; otherwise, use colored console output
    """
    # Set up standard library logging
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=getattr(logging, log_level.upper(), logging.INFO),
    )

    # Common processors
    shared_processors: list[structlog.typing.Processor] = [
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.StackInfoRenderer(),
        structlog.dev.set_exc_info,
        structlog.processors.TimeStamper(fmt="iso"),
    ]

    if log_json:
        # JSON output for production
        structlog.configure(
            processors=[
                *shared_processors,
                structlog.processors.dict_tracebacks,
                structlog.processors.JSONRenderer(),
            ],
            wrapper_class=structlog.make_filtering_bound_logger(
                getattr(logging, log_level.upper(), logging.INFO)
            ),
            context_class=dict,
            logger_factory=structlog.PrintLoggerFactory(),
            cache_logger_on_first_use=True,
        )
    else:
        # Colored console output for development
        structlog.configure(
            processors=[
                *shared_processors,
                structlog.dev.ConsoleRenderer(colors=True),
            ],
            wrapper_class=structlog.make_filtering_bound_logger(
                getattr(logging, log_level.upper(), logging.INFO)
            ),
            context_class=dict,
            logger_factory=structlog.PrintLoggerFactory(),
            cache_logger_on_first_use=True,
        )


@lru_cache
def get_logger(name: str = "agent") -> structlog.stdlib.BoundLogger:
    """Get a bound logger instance.

    Args:
        name: Logger name for context

    Returns:
        Configured structlog bound logger
    """
    return structlog.get_logger(name)
