"""
Centralized logging configuration for CodeContext.

Provides consistent logging setup and module-specific loggers.

Usage:
    # At module level:
    from logging_config import get_logger
    logger = get_logger(__name__)

    # Then in code:
    logger.info("Processing started")
    logger.debug("Details: %s", data)
    logger.error("Operation failed: %s", e)

    # At server startup:
    from logging_config import setup_logging
    setup_logging(level="DEBUG" if debug_mode else "INFO")
"""

import logging
import os
import sys
from pathlib import Path
from typing import Optional


# Module-level logger cache to avoid creating multiple loggers for same module
_loggers = {}


def setup_logging(
    level: str = "INFO",
    log_file: Optional[Path] = None,
    format_string: Optional[str] = None
) -> logging.Logger:
    """
    Configure logging for CodeContext.

    Should be called once at server/CLI startup. Subsequent calls will
    update the log level but won't recreate handlers.

    Args:
        level: Log level (DEBUG, INFO, WARNING, ERROR)
        log_file: Optional file path for logging
        format_string: Custom format string

    Returns:
        Configured root logger for codecontext
    """
    if format_string is None:
        format_string = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"

    # Get or create the codecontext root logger
    root_logger = logging.getLogger("codecontext")
    root_logger.setLevel(getattr(logging, level.upper(), logging.INFO))

    # Only add handlers if none exist (avoid duplicate handlers on multiple calls)
    if not root_logger.handlers:
        # Console handler (stderr for visibility)
        console_handler = logging.StreamHandler(sys.stderr)
        console_handler.setFormatter(logging.Formatter(format_string))
        root_logger.addHandler(console_handler)

        # File handler if specified
        if log_file:
            try:
                log_file.parent.mkdir(parents=True, exist_ok=True)
                file_handler = logging.FileHandler(log_file)
                file_handler.setFormatter(logging.Formatter(format_string))
                root_logger.addHandler(file_handler)
            except Exception as e:
                root_logger.warning(f"Could not create log file {log_file}: {e}")

    # Suppress noisy third-party loggers
    logging.getLogger("httpx").setLevel(logging.WARNING)
    logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
    logging.getLogger("httpcore").setLevel(logging.WARNING)

    # Prevent propagation to Python's root logger.
    # This is intentional: codecontext uses its own handlers and we don't want
    # messages duplicated if the root logger also has handlers configured.
    root_logger.propagate = False

    return root_logger


def get_logger(name: str) -> logging.Logger:
    """
    Get a logger for a specific module.

    Creates a child logger under the "codecontext" namespace.
    If setup_logging() hasn't been called yet, returns a basic logger.

    Args:
        name: Module name (typically __name__)

    Returns:
        Logger instance for the module

    Usage:
        from logging_config import get_logger
        logger = get_logger(__name__)
        logger.info("Processing started")
    """
    # Strip common prefixes for cleaner names
    if name.startswith("codecontext."):
        name = name[len("codecontext."):]

    # Create hierarchical logger name
    logger_name = f"codecontext.{name}" if name else "codecontext"

    # Check cache first
    if logger_name in _loggers:
        return _loggers[logger_name]

    # Create new logger
    logger = logging.getLogger(logger_name)

    # Cache it
    _loggers[logger_name] = logger

    return logger


def is_debug_mode() -> bool:
    """
    Check if debug mode is enabled via environment variable.

    Returns True if CODECONTEXT_DEBUG=1 is set.
    """
    return os.environ.get("CODECONTEXT_DEBUG", "0") == "1"


def configure_from_env() -> logging.Logger:
    """
    Configure logging based on environment variables.

    Convenience function for server/CLI startup.
    Reads CODECONTEXT_DEBUG to determine log level.

    Returns:
        Configured root logger
    """
    level = "DEBUG" if is_debug_mode() else "INFO"
    return setup_logging(level=level)
