from typing import Protocol, Tuple

from rate_limiter.core.rules import RateLimitRule
from rate_limiter.core.storage.backend import StorageBackend


class RateLimitAlgorithm(Protocol):
    """Protocol for rate limiting algorithms."""

    async def allow(
        self,
        storage: StorageBackend,
        identity: str,
        rule: RateLimitRule,
        endpoint: str = "",
    ) -> Tuple[bool, int, int]:
        """
        Check if request should be allowed.

        Args:
            storage: Storage backend
            identity: Request identity (e.g., IP address)
            rule: Rate limit rule
            endpoint: Endpoint identifier (for scoped rules)

        Returns:
            Tuple of (allowed, remaining, retry_after)
            - allowed: True if request is allowed, False otherwise
            - remaining: Number of requests remaining in window
            - retry_after: Seconds until rate limit resets
        """
        ...
