"""Simple performance monitor context manager - clean and composable.

This module provides a lightweight context manager that delegates to MetricsCollector
for data collection and can be extended with analysis capabilities.
"""

import logging
from typing import Optional

from .collector import MetricsCollector
from .metrics import PerformanceMetrics

logger = logging.getLogger(__name__)


class PerformanceMonitor:
    """Lightweight context manager for performance monitoring.

    Usage:
        with PerformanceMonitor("my_operation") as monitor:
            # ... do work ...
            pass

        # Access metrics after context exit
        print(monitor.metrics.response_time_ms)
        print(monitor.metrics.query_count)

    The monitor delegates all metric collection to MetricsCollector and
    stores the results for later access.
    """

    def __init__(self, operation_name: str, operation_type: str = "general"):
        """Initialize monitor.

        Args:
            operation_name: Name of the operation being monitored
            operation_type: Type of operation (view, model, serializer, etc.)
        """
        self.operation_name = operation_name
        self.operation_type = operation_type

        self._collector = MetricsCollector(operation_name, operation_type)
        self._metrics: Optional[PerformanceMetrics] = None

    def __enter__(self) -> "PerformanceMonitor":
        """Start monitoring."""
        logger.debug(f"Starting monitor for {self.operation_name}")
        self._collector.start()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """Stop monitoring and collect metrics."""
        self._collector.stop()
        self._metrics = self._collector.get_metrics()
        logger.debug(
            f"Stopped monitor for {self.operation_name}: "
            f"{self._metrics.response_time_ms:.2f}ms, "
            f"{self._metrics.query_count} queries"
        )

    @property
    def metrics(self) -> PerformanceMetrics:
        """Get collected metrics.

        Returns:
            PerformanceMetrics object with all collected data

        Raises:
            RuntimeError: If accessed before context manager exits
        """
        if self._metrics is None:
            raise RuntimeError(
                "Metrics not available - must be accessed after context manager exits"
            )
        return self._metrics


# Convenience factory functions for common operation types


def monitor_view(operation_name: str) -> PerformanceMonitor:
    """Create a monitor for a Django view.

    Args:
        operation_name: Name of the view being monitored

    Returns:
        PerformanceMonitor configured for view monitoring
    """
    return PerformanceMonitor(operation_name, operation_type="view")


def monitor_model(operation_name: str) -> PerformanceMonitor:
    """Create a monitor for a Django model operation.

    Args:
        operation_name: Name of the model operation being monitored

    Returns:
        PerformanceMonitor configured for model monitoring
    """
    return PerformanceMonitor(operation_name, operation_type="model")


def monitor_serializer(operation_name: str) -> PerformanceMonitor:
    """Create a monitor for a DRF serializer operation.

    Args:
        operation_name: Name of the serializer operation being monitored

    Returns:
        PerformanceMonitor configured for serializer monitoring
    """
    return PerformanceMonitor(operation_name, operation_type="serializer")


# Aliases for backward compatibility
monitor_django_view = monitor_view
monitor_django_model = monitor_model
