"""Rate limiter for ZenOTC SDK."""

from __future__ import annotations

import asyncio
import time
from collections import deque
from typing import Deque


class RateLimiter:
    """Token bucket rate limiter."""

    def __init__(self, rate: int, per_seconds: float = 1.0) -> None:
        """
        Initialize rate limiter.

        Args:
            rate: Maximum number of requests allowed
            per_seconds: Time window in seconds
        """
        self._rate = rate
        self._per_seconds = per_seconds
        self._timestamps: Deque[float] = deque()
        self._lock = asyncio.Lock()

    async def acquire(self) -> None:
        """
        Acquire permission to make a request.

        Blocks if rate limit would be exceeded.
        """
        async with self._lock:
            now = time.monotonic()

            # Remove timestamps outside the window
            window_start = now - self._per_seconds
            while self._timestamps and self._timestamps[0] < window_start:
                self._timestamps.popleft()

            # Check if we need to wait
            if len(self._timestamps) >= self._rate:
                # Calculate wait time until oldest timestamp expires
                oldest = self._timestamps[0]
                wait_time = oldest + self._per_seconds - now
                if wait_time > 0:
                    await asyncio.sleep(wait_time)
                    # Recheck after waiting
                    now = time.monotonic()
                    window_start = now - self._per_seconds
                    while self._timestamps and self._timestamps[0] < window_start:
                        self._timestamps.popleft()

            # Record this request
            self._timestamps.append(now)

    @property
    def available(self) -> int:
        """Get number of available request slots."""
        now = time.monotonic()
        window_start = now - self._per_seconds

        # Count timestamps within window
        count = sum(1 for ts in self._timestamps if ts >= window_start)
        return max(0, self._rate - count)

    def reset(self) -> None:
        """Reset the rate limiter."""
        self._timestamps.clear()
