from functools import wraps
from datetime import datetime, timedelta
import threading

class SimpleCache:
    def __init__(self):
        self._cache = {}
        self._timestamps = {}
        self._lock = threading.Lock()
    
    def get(self, key):
        with self._lock:
            if key in self._cache:
                return self._cache[key]
            return None
    
    def set(self, key, value, ttl=300):
        with self._lock:
            self._cache[key] = value
            self._timestamps[key] = datetime.now() + timedelta(seconds=ttl)
    
    def delete(self, key):
        with self._lock:
            if key in self._cache:
                del self._cache[key]
            if key in self._timestamps:
                del self._timestamps[key]
    
    def clear(self):
        with self._lock:
            self._cache.clear()
            self._timestamps.clear()
    
    def is_expired(self, key):
        if key not in self._timestamps:
            return True
        return datetime.now() > self._timestamps[key]
    
    def cleanup_expired(self):
        with self._lock:
            expired_keys = [k for k in self._timestamps if self.is_expired(k)]
            for key in expired_keys:
                self.delete(key)

_global_cache = SimpleCache()

def cached(ttl=300):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            cache_key = f"{func.__name__}:{str(args)}:{str(kwargs)}"
            
            if not _global_cache.is_expired(cache_key):
                cached_value = _global_cache.get(cache_key)
                if cached_value is not None:
                    return cached_value
            
            result = func(*args, **kwargs)
            _global_cache.set(cache_key, result, ttl)
            return result
        return wrapper
    return decorator
