"""Example Protocol specifications for augint-library.

This module demonstrates how to define Python Protocols for library interfaces.
Protocols should be written BEFORE implementation to establish clear contracts.

These protocols serve as specifications that implementations must follow.
"""

from typing import Any, Optional, Protocol


class DataProcessor(Protocol):
    """Protocol for data processing operations.

    This protocol defines the interface for processing various data types
    with configurable options and error handling.

    Example:
        >>> processor = SomeConcreteProcessor()
        >>> result = processor.process(data, timeout=30)
        >>> if result.success:
        ...     print(f"Processed {len(result.data)} items")
    """

    def process(
        self, data: Any, *, timeout: int = 30, retries: int = 3, validate: bool = True
    ) -> "ProcessingResult":
        """Process the given data with specified options.

        Args:
            data: The input data to process (any type).
            timeout: Maximum processing time in seconds.
            retries: Number of retry attempts on failure.
            validate: Whether to validate input data.

        Returns:
            ProcessingResult with success status and processed data.

        Raises:
            ValidationError: If validate=True and data is invalid.
            TimeoutError: If processing exceeds timeout.
        """
        ...

    def batch_process(
        self, data_list: list[Any], *, parallel: bool = True, chunk_size: int = 100
    ) -> list["ProcessingResult"]:
        """Process multiple data items efficiently.

        Args:
            data_list: List of data items to process.
            parallel: Whether to process items in parallel.
            chunk_size: Number of items per processing chunk.

        Returns:
            List of ProcessingResult objects, one per input item.
        """
        ...


class ProcessingResult(Protocol):
    """Protocol for processing operation results.

    Standardizes the return type for data processing operations
    with success/failure information and processed data.
    """

    @property
    def success(self) -> bool:
        """Whether the processing operation succeeded."""
        ...

    @property
    def data(self) -> Any:
        """The processed data (None if processing failed)."""
        ...

    @property
    def error(self) -> Optional[str]:
        """Error message if processing failed (None if successful)."""
        ...

    @property
    def metadata(self) -> dict[str, Any]:
        """Additional metadata about the processing operation."""
        ...


class ConfigurableClient(Protocol):
    """Protocol for configurable API clients.

    Defines interface for clients that can be configured with
    different settings and connection parameters.
    """

    def __init__(
        self,
        *,
        api_key: str,
        base_url: str = "https://api.example.com",
        timeout: int = 30,
        retries: int = 3,
    ) -> None:
        """Initialize client with configuration.

        Args:
            api_key: API key for authentication (required).
            base_url: Base URL for API requests.
            timeout: Request timeout in seconds.
            retries: Number of retry attempts.

        Raises:
            ValueError: If api_key is empty or invalid.
        """
        ...

    def get(self, endpoint: str, **params: Any) -> dict[str, Any]:
        """Make GET request to specified endpoint.

        Args:
            endpoint: API endpoint path (without base_url).
            **params: Query parameters for the request.

        Returns:
            JSON response as dictionary.

        Raises:
            APIError: If request fails after retries.
            AuthenticationError: If API key is invalid.
        """
        ...

    def post(
        self, endpoint: str, data: Optional[dict[str, Any]] = None, **params: Any
    ) -> dict[str, Any]:
        """Make POST request to specified endpoint.

        Args:
            endpoint: API endpoint path (without base_url).
            data: JSON data for request body.
            **params: Query parameters for the request.

        Returns:
            JSON response as dictionary.

        Raises:
            APIError: If request fails after retries.
            AuthenticationError: If API key is invalid.
        """
        ...


class EventHandler(Protocol):
    """Protocol for handling application events.

    Defines interface for components that process events
    with different priority levels and error handling.
    """

    def handle_event(
        self, event_type: str, event_data: dict[str, Any], *, priority: str = "normal"
    ) -> bool:
        """Handle a single event.

        Args:
            event_type: Type identifier for the event.
            event_data: Event payload data.
            priority: Event priority ("low", "normal", "high").

        Returns:
            True if event was handled successfully, False otherwise.
        """
        ...

    def can_handle(self, event_type: str) -> bool:
        """Check if this handler can process the given event type.

        Args:
            event_type: Type identifier to check.

        Returns:
            True if this handler supports the event type.
        """
        ...


class CacheProvider(Protocol):
    """Protocol for caching implementations.

    Defines interface for different caching backends
    (memory, Redis, file system, etc.).
    """

    def get(self, key: str) -> Optional[Any]:
        """Retrieve value from cache.

        Args:
            key: Cache key to retrieve.

        Returns:
            Cached value or None if key not found/expired.
        """
        ...

    def set(self, key: str, value: Any, *, ttl: Optional[int] = None) -> bool:
        """Store value in cache.

        Args:
            key: Cache key for storage.
            value: Value to cache.
            ttl: Time-to-live in seconds (None for no expiration).

        Returns:
            True if value was cached successfully.
        """
        ...

    def delete(self, key: str) -> bool:
        """Remove key from cache.

        Args:
            key: Cache key to remove.

        Returns:
            True if key was removed (or didn't exist).
        """
        ...

    def clear(self) -> bool:
        """Clear all cache entries.

        Returns:
            True if cache was cleared successfully.
        """
        ...


# Type aliases for common patterns
ProcessorFactory = Protocol
"""Factory function that creates DataProcessor instances."""

EventCallback = Protocol
"""Callback function signature for event notifications."""


# Example of Protocol composition
class AdvancedProcessor(DataProcessor, EventHandler, Protocol):
    """Protocol combining data processing with event handling.

    This demonstrates how to compose multiple protocols
    into a single interface specification.
    """

    def process_with_events(
        self, data: Any, on_progress: Optional[EventCallback] = None
    ) -> "ProcessingResult":
        """Process data while emitting progress events.

        Args:
            data: Data to process.
            on_progress: Optional callback for progress updates.

        Returns:
            ProcessingResult with final processing status.
        """
        ...
