"""
Structured logging configuration for swarm.

Provides a consistent logging interface with structured extra fields
for better observability and debugging.
"""

import logging
import sys
from typing import Any, Dict, Optional


def get_logger(name: str) -> logging.Logger:
    """
    Get a logger instance with the given name.

    Args:
        name: Logger name, typically __name__ from the calling module.

    Returns:
        Configured logger instance.
    """
    return logging.getLogger(name)


def configure_logging(
    level: str = "INFO", format_string: Optional[str] = None, json_format: bool = False
) -> None:
    """
    Configure logging for the swarm package.

    Args:
        level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
        format_string: Custom format string for log messages.
        json_format: If True, output logs in JSON format for structured logging.
    """
    if format_string is None:
        if json_format:
            # JSON format for structured logging systems
            format_string = '{"time":"%(asctime)s","level":"%(levelname)s","logger":"%(name)s","message":"%(message)s","extra":%(extra_json)s}'
        else:
            # Human-readable format with structured extra fields
            format_string = "%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(extra_fields)s"

    logging.basicConfig(
        level=getattr(logging, level.upper()), format=format_string, stream=sys.stdout
    )


class StructuredLogger:
    """
    Wrapper for structured logging with consistent extra fields.

    This class provides methods for logging with structured extra data,
    making it easier to track operations across the swarm system.
    """

    def __init__(self, logger: logging.Logger):
        """
        Initialize with a logger instance.

        Args:
            logger: The underlying logger to wrap.
        """
        self.logger = logger

    def _format_extra(self, extra: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        Format extra fields for structured logging.

        Args:
            extra: Dictionary of extra fields to include.

        Returns:
            Formatted extra dictionary.
        """
        return extra or {}

    def debug(self, message: str, extra: Optional[Dict[str, Any]] = None) -> None:
        """
        Log a debug message with optional structured data.

        Args:
            message: The log message.
            extra: Optional dictionary of structured data.
        """
        self.logger.debug(message, extra=self._format_extra(extra))

    def info(self, message: str, extra: Optional[Dict[str, Any]] = None) -> None:
        """
        Log an info message with optional structured data.

        Args:
            message: The log message.
            extra: Optional dictionary of structured data.
        """
        self.logger.info(message, extra=self._format_extra(extra))

    def warning(self, message: str, extra: Optional[Dict[str, Any]] = None) -> None:
        """
        Log a warning message with optional structured data.

        Args:
            message: The log message.
            extra: Optional dictionary of structured data.
        """
        self.logger.warning(message, extra=self._format_extra(extra))

    def error(
        self,
        message: str,
        extra: Optional[Dict[str, Any]] = None,
        exc_info: bool = False,
    ) -> None:
        """
        Log an error message with optional structured data.

        Args:
            message: The log message.
            extra: Optional dictionary of structured data.
            exc_info: If True, include exception traceback.
        """
        self.logger.error(message, extra=self._format_extra(extra), exc_info=exc_info)

    def critical(
        self,
        message: str,
        extra: Optional[Dict[str, Any]] = None,
        exc_info: bool = False,
    ) -> None:
        """
        Log a critical message with optional structured data.

        Args:
            message: The log message.
            extra: Optional dictionary of structured data.
            exc_info: If True, include exception traceback.
        """
        self.logger.critical(
            message, extra=self._format_extra(extra), exc_info=exc_info
        )


def get_structured_logger(name: str) -> StructuredLogger:
    """
    Get a structured logger instance.

    Args:
        name: Logger name, typically __name__ from the calling module.

    Returns:
        StructuredLogger instance for consistent logging.
    """
    return StructuredLogger(get_logger(name))
