"""
Context managers for error capture
"""

from contextlib import contextmanager
from typing import Optional, Dict, Any, Generator, TYPE_CHECKING

from ..models.captured_models import (
    CaptureConfig,
    PipelineComponent,
    Severity,
    EventType,
)

@contextmanager
def capture_context(
    component: Optional[PipelineComponent] = None,
    component_name: Optional[str] = None,
    pipeline_name: Optional[str] = None,
    engine_name: Optional[str] = None,
    severity: Severity = Severity.HIGH,
    event_type: EventType = EventType.ERROR,
    reraise: bool = True,
    log_to_console: bool = True,
    send_to_transport: bool = True,
    metadata: Optional[Dict[str, Any]] = None,
) -> Generator[None, None, None]:
    """
    Context manager for capturing errors in code blocks.
    
    Example:
        with capture_context(
            component=PipelineComponent.TRANSFORMATION,
            pipeline_name='etl_pipeline'
        ):
            process_data()

    Args:
        component: Pipeline component type
        component_name: Custom component name
        pipeline_name: Pipeline name
        engine_name: Processing engine name
        severity: Error severity
        event_type: Event type
        reraise: Whether to reraise exceptions
        log_to_console: Whether to log to console
        send_to_transport: Whether to send to transport
        metadata: Additional metadata
    """
    # Import here to avoid circular imports
    from ..services.error_capture import get_capture_service
    
    config = CaptureConfig(
        component=component,
        component_name=component_name,
        pipeline_name=pipeline_name,
        engine_name=engine_name,
        severity=severity,
        event_type=event_type,
        reraise=reraise,
        log_to_console=log_to_console,
        send_to_transport=send_to_transport,
        metadata=metadata or {},
    )

    try:
        yield
    except Exception as e:
        service = get_capture_service()
        service.capture_exception(e, config=config)
        # Exception will be reraised if reraise=True


@contextmanager
def capture_warnings(
    component: Optional[PipelineComponent] = None,
    pipeline_name: Optional[str] = None,
    metadata: Optional[Dict[str, Any]] = None,
) -> Generator[None, None, None]:
    """
    Context manager for capturing non-critical warnings.

    Example:
        with capture_warnings(component=PipelineComponent.API):
            # Warnings will be captured but not raised
            make_api_call()

    Args:
        component: Pipeline component type
        pipeline_name: Pipeline name
        metadata: Additional metadata
    """
    # Import here to avoid circular imports
    from ..services.error_capture import get_capture_service
    
    config = CaptureConfig(
        component=component,
        pipeline_name=pipeline_name,
        severity=Severity.WARNING,
        event_type=EventType.WARNING,
        reraise=False,  # Don't reraise warnings
        metadata=metadata or {},
    )

    try:
        yield
    except Exception as e:
        service = get_capture_service()
        service.capture_exception(e, config=config)
        # Exception is captured but not reraised

@contextmanager
def suppress_and_capture(
    component: Optional[PipelineComponent] = None,
    pipeline_name: Optional[str] = None,
    severity: Severity = Severity.LOW,
    metadata: Optional[Dict[str, Any]] = None,
) -> Generator[None, None, None]:
    """
    Context manager that suppresses exceptions but captures them.

    Example:
        with suppress_and_capture(component=PipelineComponent.API):
            # Exceptions will be captured but not raised
            optional_api_call()

    Args:
        component: Pipeline component type
        pipeline_name: Pipeline name
        severity: Error severity
        metadata: Additional metadata
    """
    # Import here to avoid circular imports
    from ..services.error_capture import get_capture_service
    
    config = CaptureConfig(
        component=component,
        pipeline_name=pipeline_name,
        severity=severity,
        reraise=False,
        metadata=metadata or {},
    )

    try:
        yield
    except Exception as e:
        service = get_capture_service()
        service.capture_exception(e, config=config)
        # Exception is suppressed