"""Centralized logging infrastructure for qldata.

Provides consistent logging across all modules with performance tracking.
"""

import functools
import logging
import time
from typing import Any, Callable, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")


def get_logger(name: str) -> logging.Logger:
    """Get a logger instance for a module.
    
    Args:
        name: Module name (typically __name__)
        
    Returns:
        Configured logger instance
        
    Example:
        >>> logger = get_logger(__name__)
        >>> logger.info("Processing data")
    """
    return logging.getLogger(f"qldata.{name}")


def timed(func: Callable[P, R]) -> Callable[P, R]:
    """Decorator to log function execution time.
    
    Logs at DEBUG level with function name and duration.
    
    Example:
        >>> @timed
        ... def fetch_data():
        ...     return data
    """
    logger = logging.getLogger(f"qldata.{func.__module__}")
    
    @functools.wraps(func)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        logger.debug(f"{func.__name__} took {elapsed:.3f}s")
        return result
    
    return wrapper


def log_operation(operation: str, **context: Any) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """Decorator to log operations with context.
    
    Args:
        operation: Operation description
        **context: Additional context to log
        
    Example:
        >>> @log_operation("fetch_bars", source="binance")
        ... def fetch_bars(symbol):
        ...     return data
    """
    def decorator(func: Callable[P, R]) -> Callable[P, R]:
        logger = logging.getLogger(f"qldata.{func.__module__}")
        
        @functools.wraps(func)
        def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
            ctx_str = ", ".join(f"{k}={v}" for k, v in context.items())
            logger.debug(f"{operation} started ({ctx_str})")
            
            try:
                result = func(*args, **kwargs)
                logger.debug(f"{operation} completed successfully")
                return result
            except Exception as e:
                logger.error(f"{operation} failed: {e}")
                raise
        
        return wrapper
    return decorator


__all__ = ["get_logger", "timed", "log_operation"]
