from datetime import datetime, timedelta, timezone
from typing import Any, override

from phederation.cache.base import BaseCache


class DictCache(BaseCache):
    def __init__(self, max_size: int = 100, ttl: int = 300):
        self.max_size: int = max_size
        self.ttl: int = ttl
        self._cache: dict[str, tuple[Any | None, datetime]] = {}

    @override
    def get(self, key: str) -> None | Any:
        if key in self._cache:
            value, timestamp = self._cache[key]
            if datetime.now(timezone.utc) - timestamp < timedelta(seconds=self.ttl):
                return value
            else:
                del self._cache[key]
        return None

    @override
    def set(self, key: str, value: Any | None):
        if len(self._cache) >= self.max_size:
            oldest_key = min(self._cache, key=lambda k: self._cache[k][1])
            del self._cache[oldest_key]
        self._cache[key] = (value, datetime.now(timezone.utc))

    @override
    def delete(self, key: str):
        _ = self._cache.pop(key, None)

    @override
    def clear(self, prefix: str | None = None):
        if not prefix:
            self._cache.clear()
        else:
            keys = list(self._cache.keys())
            for key in keys:
                if key.startswith(prefix):
                    _ = self._cache.pop(key)

    @override
    def close(self):
        self.clear()
