"""Logging configuration — all output forced to stderr for MCP stdio transport."""

import builtins
import logging
import sys
from typing import Any

import structlog

_original_print = builtins.print


def _redirect_print_to_stderr() -> None:
    """Globally redirect print() to stderr.

    Safe because fastmcp uses sys.stdout.buffer.write() for JSON-RPC, not print().
    """

    def stderr_print(*args: Any, **kwargs: Any) -> None:
        if "file" not in kwargs or kwargs["file"] is sys.stdout:
            kwargs["file"] = sys.stderr
        _original_print(*args, **kwargs)

    builtins.print = stderr_print


def _patch_mobile_use_logger() -> None:
    """Patch the minitap-mobile-use SDK logger to use stderr instead of stdout."""
    try:
        from minitap.mobile_use.utils import logger as sdk_logger_module
        from minitap.mobile_use.utils.logger import MobileUseLogger

        original_setup_console = MobileUseLogger._setup_console_handler

        def patched_setup_console(self: MobileUseLogger, level: str) -> None:
            original_setup_console(self, level)
            for handler in self.logger.handlers:
                if isinstance(handler, logging.StreamHandler) and handler.stream == sys.stdout:
                    handler.setStream(sys.stderr)

        MobileUseLogger._setup_console_handler = patched_setup_console

        # Patch existing loggers that were created before this patch ran
        existing_loggers = getattr(sdk_logger_module, "_loggers", {})
        for logger_instance in existing_loggers.values():
            if isinstance(logger_instance, MobileUseLogger):
                for handler in logger_instance.logger.handlers:
                    if isinstance(handler, logging.StreamHandler) and handler.stream == sys.stdout:
                        handler.setStream(sys.stderr)

    except ImportError:
        pass


def configure_logging(log_level: str = "INFO") -> None:
    """Configure structlog — all output to stderr, stdout reserved for MCP JSON-RPC."""
    _redirect_print_to_stderr()
    _patch_mobile_use_logger()

    level = getattr(logging, log_level.upper())

    root_logger = logging.getLogger()
    root_logger.setLevel(level)
    root_logger.handlers.clear()

    stderr_handler = logging.StreamHandler(sys.stderr)
    stderr_handler.setFormatter(logging.Formatter("%(message)s"))
    root_logger.addHandler(stderr_handler)

    structlog.configure(
        processors=[
            structlog.stdlib.add_log_level,
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.CallsiteParameterAdder(
                parameters=[
                    structlog.processors.CallsiteParameter.FILENAME,
                    structlog.processors.CallsiteParameter.LINENO,
                    structlog.processors.CallsiteParameter.FUNC_NAME,
                ]
            ),
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.JSONRenderer(),
        ],
        wrapper_class=structlog.stdlib.BoundLogger,
        context_class=dict,
        logger_factory=structlog.stdlib.LoggerFactory(),
        cache_logger_on_first_use=True,
    )


def get_logger(name: str) -> structlog.stdlib.BoundLogger:
    return structlog.get_logger(name)
