"""Offline buffer implementation for storing data points when network is unavailable.

OfflineBuffer implements a circular FIFO buffer for storing data points
when the network is unavailable.

Features:
- FIFO (First-In-First-Out) behavior
- Circular buffer: oldest points are dropped when capacity is reached
- Default capacity: 10,000 points
"""

from .types import BufferStats, IngressDataPoint


class OfflineBuffer:
    """Circular FIFO buffer for offline data storage."""

    def __init__(self, max_size: int = 10000) -> None:
        """Initialize offline buffer.

        Args:
            max_size: Maximum number of points to store (default: 10000)
        """
        self._buffer: list[IngressDataPoint] = []
        self._max_size = max_size

    def add(self, point: IngressDataPoint) -> None:
        """Add a data point to the buffer.

        If the buffer is full, the oldest point is removed (circular behavior).

        Args:
            point: Data point to add
        """
        self._buffer.append(point)

        # Drop oldest if exceeding max size (circular buffer behavior)
        if len(self._buffer) > self._max_size:
            self._buffer.pop(0)

    def drain(self) -> list[IngressDataPoint]:
        """Drain all points from the buffer and return them.

        The buffer is cleared after draining.

        Returns:
            List of all buffered points
        """
        points = self._buffer.copy()
        self._buffer = []
        return points

    def get_stats(self) -> BufferStats:
        """Get buffer statistics.

        Returns:
            Buffer statistics (size, max_size, is_at_capacity)
        """
        return BufferStats(
            size=len(self._buffer),
            max_size=self._max_size,
            is_at_capacity=len(self._buffer) >= self._max_size,
        )

    def clear(self) -> None:
        """Clear all points from the buffer without returning them."""
        self._buffer = []

    def is_empty(self) -> bool:
        """Check if the buffer is empty.

        Returns:
            True if buffer contains no points
        """
        return len(self._buffer) == 0

    def is_full(self) -> bool:
        """Check if the buffer is at capacity.

        Returns:
            True if buffer is at maximum capacity
        """
        return len(self._buffer) >= self._max_size
