"""
Standalone Integration for Storm Logger

This module provides framework-agnostic logging functionality, making Storm Logger
ideal for standalone Python applications, scripts, CLI tools, and batch jobs.

Key Components:
- StandaloneStormLogger: Framework-agnostic logger class
- Configuration functions for standalone applications
- Context detection for common app patterns
- Integration helpers for scripts and CLI tools

Example:
    # Quick setup for a script
    from storm_logger.integrations.standalone import get_standalone_logger

    logger = get_standalone_logger(__name__)
    logger.info("Script started")

    # Or with configuration
    from storm_logger import StormLoggerConfig
    from storm_logger.integrations.standalone import configure_standalone_logging

    config = StormLoggerConfig(log_level="DEBUG")
    configure_standalone_logging(config)
"""

import logging
import logging.config
import os
from typing import Any

from ..config import Framework, LogLevel, StormLoggerConfig
from ..core.base import create_base_logging_config
from ..core.logger import StormLogger


class StandaloneStormLogger(StormLogger):
    """
    Standalone Storm Logger for framework-agnostic applications.

    This class provides Storm Logger functionality without any
    framework-specific dependencies or features.
    """

    def __init__(
        self,
        name: str,
        config: StormLoggerConfig | None = None,
        auto_detect_context: bool = True,
    ):
        super().__init__(name, config, auto_detect_context)

        # Ensure framework is set to standalone
        if self.config.framework != Framework.STANDALONE:
            self.config.framework = Framework.STANDALONE

    def _configure_handlers(self) -> None:
        """Configure standalone log handlers."""
        logging_config = create_standalone_logging_config(self.config)

        # Apply the logging configuration
        logging.config.dictConfig(logging_config)


def create_standalone_logging_config(config: StormLoggerConfig) -> dict[str, Any]:
    """
    Create standalone logging configuration.

    This creates a clean, framework-agnostic logging configuration
    suitable for any Python application, including scripts, CLI tools,
    services, and batch jobs.

    Args:
        config: Storm Logger configuration object

    Returns:
        Logging configuration dictionary compatible with logging.config.dictConfig

    Example:
        config = StormLoggerConfig(production_mode=True)
        logging_dict = create_standalone_logging_config(config)
        logging.config.dictConfig(logging_dict)
    """
    # Start with base configuration
    logging_config = create_base_logging_config(config)

    # Add standalone-specific configurations
    # Add app loggers first so production handlers can modify them
    _add_app_loggers(logging_config, config)
    _add_production_handlers(logging_config, config)

    return logging_config


def _add_production_handlers(logging_config: dict[str, Any], config: StormLoggerConfig) -> None:
    """
    Add production-specific handlers to the logging configuration.

    This includes syslog support for POSIX systems and ensures all loggers
    are configured for production use.

    Args:
        logging_config: The logging configuration dictionary to modify
        config: Storm Logger configuration
    """
    if not config.production_mode:
        return

    # Add syslog handler for production (Unix systems only)
    if os.name == "posix":
        _add_syslog_handler(logging_config)
        _add_syslog_to_loggers(logging_config)


def _add_syslog_handler(logging_config: dict[str, Any]) -> None:
    """
    Add syslog handler configuration.

    Creates a syslog handler for POSIX systems to send logs to the system logger.
    """
    logging_config["handlers"]["syslog"] = {
        "level": "INFO",
        "class": "logging.handlers.SysLogHandler",
        "formatter": "standard",
        "address": "/dev/log",
    }


def _add_syslog_to_loggers(logging_config: dict[str, Any]) -> None:
    """
    Add syslog handler to all configured loggers.

    Ensures all loggers send their output to syslog in production.
    """
    for logger_config in logging_config["loggers"].values():
        # Ensure handlers list exists
        if "handlers" not in logger_config:
            logger_config["handlers"] = []

        # Add syslog if not present
        if "syslog" not in logger_config["handlers"]:
            logger_config["handlers"].append("syslog")


def _add_app_loggers(logging_config: dict[str, Any], config: StormLoggerConfig) -> None:
    """
    Configure application-specific loggers.

    Sets up loggers for common application components like services,
    workers, schedulers, etc.

    Args:
        logging_config: The logging configuration dictionary to modify
        config: Storm Logger configuration
    """
    app_loggers = _get_app_logger_names()

    for logger_name in app_loggers:
        handlers = _configure_handler_list(config)
        logging_config["loggers"][logger_name] = {
            "handlers": handlers,
            "level": config.log_level.value,
            "propagate": False,
        }


def _get_app_logger_names() -> list[str]:
    """
    Get list of standard application logger names.

    Returns:
        List of logger names commonly used in standalone applications
    """
    return [
        "app",
        "application",
        "main",
        "core",
        "service",
        "worker",
        "scheduler",
        "cli",
        "script",
        "batch",
        "etl",
        "pipeline",
        "processor",
        "daemon",
    ]


def _configure_handler_list(config: StormLoggerConfig) -> list[str]:
    """
    Build the list of handlers based on configuration.

    Args:
        config: Storm Logger configuration

    Returns:
        List of handler names to use
    """
    handlers = ["console"]

    if config.enable_file_logging:
        handlers.extend(["app_file", "error_file"])

        if config.debug_mode:
            handlers.append("debug_file")

    return handlers


def configure_standalone_logging(config: StormLoggerConfig | None = None) -> None:
    """
    Configure standalone logging with Storm Logger.

    This function sets up framework-agnostic logging configuration
    suitable for any Python application.

    Args:
        config: Optional Storm Logger configuration
    """
    from ..config import get_config, set_config

    if config is None:
        config = get_config()

    # Ensure framework is set to standalone
    config.framework = Framework.STANDALONE
    set_config(config)

    # Create standalone logging configuration
    logging_config = create_standalone_logging_config(config)

    # Set up directories
    config.create_log_directories()

    # Apply configuration
    logging.config.dictConfig(logging_config)


def get_standalone_logger(
    name: str, config: StormLoggerConfig | None = None
) -> StandaloneStormLogger:
    """
    Get a standalone Storm Logger instance.

    Args:
        name: Logger name
        config: Optional configuration

    Returns:
        StandaloneStormLogger instance
    """
    return StandaloneStormLogger(name, config)


# Standalone-specific context detection patterns
STANDALONE_CONTEXT_PATTERNS = {
    "main": ["main.py", "__main__", "main"],
    "service": ["service.py", "service", "Service"],
    "worker": ["worker.py", "worker", "Worker"],
    "scheduler": ["scheduler.py", "schedule", "Scheduler"],
    "api": ["api.py", "api", "API"],
    "cli": ["cli.py", "command", "CLI"],
    "config": ["config.py", "configuration", "Config"],
    "database": ["database.py", "db.py", "Database"],
    "cache": ["cache.py", "redis", "Cache"],
    "queue": ["queue.py", "celery", "Queue"],
    "test": ["test_", "tests.py", "TestCase"],
    "util": ["util.py", "utils.py", "helper"],
    "exception": ["exception.py", "error.py", "Exception"],
    "validation": ["validation.py", "validator", "Validator"],
    "security": ["security.py", "auth.py", "Security"],
    "monitoring": ["monitoring.py", "metrics.py", "Monitor"],
    "script": ["script.py", "run.py", "execute.py"],
    "batch": ["batch.py", "job.py", "task.py"],
    "etl": ["etl.py", "extract", "transform", "load"],
    "pipeline": ["pipeline.py", "flow.py", "workflow.py"],
}


def detect_standalone_context(frame_info: Any) -> str:
    """
    Detect standalone application context from frame information.

    This function analyzes Python frame information to determine
    the application component context (cli, service, worker, etc.).

    Args:
        frame_info: Python frame information object

    Returns:
        Standalone context string (e.g., "app.cli", "app.service")

    Example:
        context = detect_standalone_context(inspect.currentframe())
        # Returns: "app.cli" if called from a CLI command
    """
    filename = frame_info.filename.lower()
    function_name = frame_info.function.lower()

    # Check standalone-specific patterns
    for context, patterns in STANDALONE_CONTEXT_PATTERNS.items():
        for pattern in patterns:
            if pattern in filename or pattern in function_name:
                return f"app.{context}"

    # Check for common Python patterns
    if "__init__" in function_name:
        return "app.initialization"
    elif "setup" in function_name:
        return "app.setup"
    elif "cleanup" in function_name:
        return "app.cleanup"

    # Default standalone context
    return "app.general"


# Additional utility functions for standalone applications


def setup_script_logging(
    script_name: str, log_level: str = "INFO", log_to_file: bool = True, **kwargs: Any
) -> StandaloneStormLogger:
    """
    Quick setup for script logging.

    Provides a convenient way to set up logging for Python scripts
    with sensible defaults.

    Args:
        script_name: Name of the script
        log_level: Logging level (default: INFO)
        log_to_file: Whether to log to file (default: True)
        **kwargs: Additional configuration options

    Returns:
        Configured StandaloneStormLogger instance

    Example:
        logger = setup_script_logging("data_processor.py", log_level="DEBUG")
        logger.info("Script started")
    """
    config = StormLoggerConfig(
        log_level=LogLevel(log_level.upper()),
        enable_file_logging=log_to_file,
        enable_console=True,
        **kwargs,
    )

    configure_standalone_logging(config)
    return get_standalone_logger(script_name)


def setup_cli_logging(
    app_name: str, verbosity: int = 0, quiet: bool = False, **kwargs: Any
) -> StandaloneStormLogger:
    """
    Setup logging for CLI applications.

    Configures logging based on common CLI patterns with support
    for verbosity levels and quiet mode.

    Args:
        app_name: Name of the CLI application
        verbosity: Verbosity level (0=normal, 1=verbose, 2+=debug)
        quiet: Suppress non-error output
        **kwargs: Additional configuration options

    Returns:
        Configured StandaloneStormLogger instance

    Example:
        # In your CLI app
        logger = setup_cli_logging("myapp", verbosity=args.verbose, quiet=args.quiet)
    """
    # Determine log level based on verbosity and quiet mode
    VERBOSE_DEBUG_THRESHOLD = 2
    if quiet:
        log_level = LogLevel.ERROR
    elif verbosity >= VERBOSE_DEBUG_THRESHOLD:
        log_level = LogLevel.DEBUG
    elif verbosity == 1:
        log_level = LogLevel.INFO
    else:
        log_level = LogLevel.WARNING

    config = StormLoggerConfig(
        log_level=log_level,
        enable_console=True,
        enable_file_logging=verbosity > 0,  # Only log to file in verbose mode
        console_colors=not quiet,
        **kwargs,
    )

    configure_standalone_logging(config)
    return get_standalone_logger(app_name)


class ScriptProgressLogger:
    """
    Helper class for logging script progress.

    Provides convenient methods for tracking progress in batch jobs,
    data processing scripts, and long-running operations.

    Example:
        progress = ScriptProgressLogger("data_import")

        progress.start("Importing customer data")
        for i, record in enumerate(records):
            progress.update(i, len(records), f"Processing {record.id}")
            # Process record
        progress.complete("Imported {count} records")
    """

    def __init__(self, logger_name: str):
        """Initialize progress logger."""
        self.logger = get_standalone_logger(logger_name)
        self.start_time: float | None = None
        self.operation: str | None = None

    def start(self, operation: str) -> None:
        """Start tracking an operation."""
        import time

        self.start_time = time.time()
        self.operation = operation
        self.logger.info(f"Started: {operation}")

    def update(self, current: int, total: int, message: str = "") -> None:
        """Update progress."""
        if total > 0:
            percentage = (current / total) * 100
            self.logger.info(f"Progress: {percentage:.1f}% ({current}/{total}) - {message}")

    def complete(self, message: str = "Operation completed") -> None:
        """Mark operation as complete."""
        if self.start_time:
            import time

            duration = time.time() - self.start_time
            self.logger.info(f"Completed: {self.operation} - {message} (Duration: {duration:.2f}s)")
        else:
            self.logger.info(message)
