from __future__ import annotations

"""Sliding-window memory backend."""

from collections import deque
from dataclasses import dataclass, field

from agentrspy.core import Memory, Message, Role


@dataclass(slots=True)
class SlidingWindowMemory(Memory):
    """Memory backend that keeps a fixed number of recent non-system messages."""

    window_size: int
    system_message: Message | None = None
    messages: deque[Message] = field(default_factory=deque)

    @classmethod
    def new(cls, window_size: int) -> "SlidingWindowMemory":
        return cls(window_size=window_size)

    async def store(self, key: str, value: Message) -> None:
        del key
        if value.role is Role.SYSTEM:
            self.system_message = value
            return
        self.messages.append(value)
        while len(self.messages) > self.window_size:
            self.messages.popleft()

    async def retrieve(self, query: str, limit: int) -> list[Message]:
        lowered = query.lower()
        return [
            message
            for message in self.messages
            if lowered in message.text_content().lower()
        ][:limit]

    async def history(self) -> list[Message]:
        history: list[Message] = []
        if self.system_message is not None:
            history.append(self.system_message)
        history.extend(self.messages)
        return history

    async def clear(self) -> None:
        self.messages.clear()

    async def token_count(self) -> int:
        return sum(len(message.text_content()) // 4 for message in self.messages)
