"""
简单的内存缓存服务
用于缓存COUNT查询结果，减少数据库负载
"""

import hashlib
import json
import time
from typing import Any, Dict, Optional
from datetime import datetime, timedelta

class CacheService:
    """内存缓存服务"""
    
    def __init__(self, default_ttl: int = 300):
        """
        初始化缓存服务
        
        Args:
            default_ttl: 默认缓存时间（秒），默认5分钟
        """
        self._cache: Dict[str, Dict[str, Any]] = {}
        self.default_ttl = default_ttl
        self._last_cleanup = time.time()
        self._cleanup_interval = 60  # 每60秒清理一次过期缓存
    
    def _generate_key(self, prefix: str, params: Dict[str, Any]) -> str:
        """
        生成缓存键
        
        Args:
            prefix: 缓存键前缀
            params: 参数字典
            
        Returns:
            缓存键
        """
        # 将参数排序并序列化，确保相同参数生成相同的键
        sorted_params = json.dumps(params, sort_keys=True)
        hash_value = hashlib.md5(sorted_params.encode()).hexdigest()[:16]
        return f"{prefix}:{hash_value}"
    
    def get(self, key: str) -> Optional[Any]:
        """
        获取缓存值
        
        Args:
            key: 缓存键
            
        Returns:
            缓存值，如果不存在或过期返回None
        """
        # 定期清理过期缓存
        if time.time() - self._last_cleanup > self._cleanup_interval:
            self._cleanup_expired()
        
        if key in self._cache:
            cache_entry = self._cache[key]
            if cache_entry['expires_at'] > time.time():
                cache_entry['hits'] += 1
                return cache_entry['value']
            else:
                # 缓存已过期，删除
                del self._cache[key]
        
        return None
    
    def set(self, key: str, value: Any, ttl: Optional[int] = None) -> None:
        """
        设置缓存值
        
        Args:
            key: 缓存键
            value: 缓存值
            ttl: 缓存时间（秒），如果不指定使用默认值
        """
        ttl = ttl or self.default_ttl
        self._cache[key] = {
            'value': value,
            'expires_at': time.time() + ttl,
            'created_at': time.time(),
            'hits': 0
        }
    
    def delete(self, key: str) -> bool:
        """
        删除缓存
        
        Args:
            key: 缓存键
            
        Returns:
            是否删除成功
        """
        if key in self._cache:
            del self._cache[key]
            return True
        return False
    
    def clear(self, prefix: Optional[str] = None) -> int:
        """
        清除缓存
        
        Args:
            prefix: 如果指定，只清除以该前缀开头的缓存
            
        Returns:
            清除的缓存数量
        """
        if prefix:
            keys_to_delete = [k for k in self._cache.keys() if k.startswith(prefix)]
            for key in keys_to_delete:
                del self._cache[key]
            return len(keys_to_delete)
        else:
            count = len(self._cache)
            self._cache.clear()
            return count
    
    def _cleanup_expired(self) -> int:
        """
        清理过期缓存
        
        Returns:
            清理的缓存数量
        """
        current_time = time.time()
        expired_keys = [
            key for key, entry in self._cache.items()
            if entry['expires_at'] <= current_time
        ]
        
        for key in expired_keys:
            del self._cache[key]
        
        self._last_cleanup = current_time
        return len(expired_keys)
    
    def get_stats(self) -> Dict[str, Any]:
        """
        获取缓存统计信息
        
        Returns:
            统计信息字典
        """
        current_time = time.time()
        total_size = len(self._cache)
        expired_count = sum(
            1 for entry in self._cache.values()
            if entry['expires_at'] <= current_time
        )
        
        total_hits = sum(entry['hits'] for entry in self._cache.values())
        
        return {
            'total_entries': total_size,
            'expired_entries': expired_count,
            'active_entries': total_size - expired_count,
            'total_hits': total_hits,
            'cache_size_bytes': self._estimate_size(),
            'last_cleanup': datetime.fromtimestamp(self._last_cleanup).isoformat()
        }
    
    def _estimate_size(self) -> int:
        """
        估算缓存占用的内存大小（字节）
        
        Returns:
            估算的字节数
        """
        # 简单估算，实际大小可能有差异
        import sys
        total_size = 0
        for key, entry in self._cache.items():
            total_size += sys.getsizeof(key)
            total_size += sys.getsizeof(entry)
            if isinstance(entry['value'], (dict, list, str)):
                total_size += sys.getsizeof(entry['value'])
        return total_size

# 全局缓存实例
cache_service = CacheService(default_ttl=300)  # 5分钟默认缓存