"""Logging configuration for wafer.
Tiger Style: Explicit configuration, bounded resources, fail-fast.
"""
import logging.config
import os
from typing import Any
from .bridge import is_log_bridge_set
def setup_logging(
    level: str | None = None,
    console_level: str | None = None,
    use_json: bool | None = None,
    use_rich: bool | None = None,
    use_color: bool | None = None,
    logger_levels: dict[str, str] | None = None,
    log_file: str | None = None,
    rich_tracebacks: bool = False,
    use_queue_handler: bool = True,
    max_log_bytes: int = 100_000_000,
    backup_count: int = 5,
) -> None:
    """Setup standardized logging configuration using dict config.
    Tiger Style: Bounded log files, explicit parameters, assertions.
    Args:
        level: Default log level for root logger (default: INFO or LOG_LEVEL env var)
        console_level: Log level for console handler (default: same as level).
                      Set to "CRITICAL" to suppress console output while still logging to file.
        use_json: Whether to use JSON formatter for console (default: False for human-readable)
        use_rich: Whether to use RichHandler for console output (default: False).
                 If True, produces clean CLI output with colors and formatting.
                 Overridden to False if use_json=True or use_color=True.
        use_color: Whether to use ANSI color formatter for console (default: False).
                  If True, produces colorized output with minimal formatting.
                  Format: [HH:MM:SS] message (color indicates level).
                  Overrides use_rich if both are True.
        logger_levels: Dict mapping logger names to specific log levels
                      e.g. {"httpx": "WARNING", "paramiko": "ERROR"}
        log_file: Optional log file path. If provided, logs in JSONL format to file
                 with automatic rotation when file reaches max_log_bytes
        rich_tracebacks: Whether to enable rich tracebacks (only applies when use_rich=True)
        use_queue_handler: Whether to use QueueHandler for async-safe logging (default: True).
                          Recommended for async code (trio/asyncio) to prevent blocking.
        max_log_bytes: Maximum bytes per log file before rotation (default: 100MB).
                       Tiger Style: All files must be bounded!
        backup_count: Number of rotated log files to keep (default: 5)
    Returns:
        None. Configures Python's global logging state.
    Example:
        >>> from wafer_core.logging import setup_logging
        >>> setup_logging(level="DEBUG", log_file="logs/app.jsonl")
        >>> import logging
        >>> logger = logging.getLogger(__name__)
        >>> logger.info("Application started")
    """
    # Tiger Style: Assert preconditions
    assert max_log_bytes > 0, f"max_log_bytes must be > 0, got {max_log_bytes}"
    assert backup_count >= 0, f"backup_count must be >= 0, got {backup_count}"
    level = level or os.getenv("LOG_LEVEL", "INFO")
    console_level = console_level or level  # Default to same as root level
    use_json = use_json if use_json is not None else os.getenv("LOG_JSON", "").lower() == "true"
    use_rich = use_rich if use_rich is not None else False
    use_color = use_color if use_color is not None else False
    logger_levels = logger_levels or {}
    # JSON mode and color mode override rich mode
    if use_json or use_color:
        use_rich = False
    formatters: dict[str, Any] = {
        "standard": {
            "format": "[%(asctime)s] %(levelname)s: %(message)s",
            "datefmt": "%H:%M:%S",
        },
        "minimal": {"format": "%(message)s"},
        "color": {
            "()": "wafer_core.logging.color_formatter.ColorFormatter",
            "show_timestamp": True,
        },
        "json": {
            "()": "wafer_core.logging.json_formatter.JSONFormatter",
            "fmt_keys": {
                "level": "levelname",
                "logger": "name",
                "module": "module",
                "function": "funcName",
                "line": "lineno",
            },
        },
    }
    # Choose handler and formatter based on mode
    handlers: dict[str, Any]
    if use_rich:
        handlers = {
            "console": {
                "class": "rich.logging.RichHandler",
                "level": console_level,
                "formatter": "minimal",
                "rich_tracebacks": rich_tracebacks,
                "show_time": False,
                "show_path": False,
            }
        }
    else:

        console_formatter = "standard"  # Default
        if use_json:
            console_formatter = "json"
        elif use_color:
            console_formatter = "color"
        handlers = {
            "console": {
                "class": "logging.StreamHandler",
                "level": console_level,
                "formatter": console_formatter,
                "stream": "ext://sys.stdout",
            }
        }
    # Tiger Style: Bounded! Use RotatingFileHandler to prevent unbounded growth
    handler_list = ["console"]
    if log_file:
        handlers["file"] = {
            "class": "logging.handlers.RotatingFileHandler",
            "level": "DEBUG",
            "formatter": "json",  # Always use JSON for file output
            "filename": log_file,
            "mode": "a",
            "maxBytes": max_log_bytes,  # Tiger: Bounded!
            "backupCount": backup_count,  # Keep N rotated files
        }
        handler_list.append("file")
    # Note: Bridge must be set BEFORE calling setup_logging() for this to work
    if is_log_bridge_set():
        handlers["bridge"] = {
            "()": "wafer_core.logging.bridge.LogBridgeHandler",
            "level": "DEBUG",
            "formatter": "standard",  # Use standard formatter for bridge
        }
        handler_list.append("bridge")
    # mCoding pattern: Use QueueHandler for async-safe logging
    # Python 3.12+ QueueHandler in dictConfig automatically creates QueueListener!
    # The listener runs in a background thread, prevents blocking in async code
    if use_queue_handler:
        handlers["queue_handler"] = {
            "class": "logging.handlers.QueueHandler",
            "handlers": handler_list.copy(),  # Wrap our actual handlers
            "respect_handler_level": True,  # Each handler keeps its own level
        }
        handler_list = ["queue_handler"]  # Route all logs through queue
    config: dict[str, Any] = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": formatters,
        "handlers": handlers,
        "loggers": {},
        "root": {"level": level, "handlers": handler_list},
    }
    loggers_config = config["loggers"]
    assert isinstance(loggers_config, dict), "loggers must be dict"
    for logger_name, logger_level in logger_levels.items():
        # mCoding: only set level, no handlers - let messages propagate to root
        loggers_config[logger_name] = {"level": logger_level}
    logging.config.dictConfig(config)
    # mCoding pattern: Start QueueListener and register cleanup
    # Python 3.12+ creates the listener automatically, we just need to start it
    if use_queue_handler:
        queue_handler = logging.getHandlerByName("queue_handler")
        if queue_handler is not None and hasattr(queue_handler, "listener"):
            queue_handler.listener.start()
            # Register cleanup on exit (mCoding pattern)
            import atexit
            atexit.register(queue_handler.listener.stop)
