"""Cache module for models."""

from __future__ import annotations

import time
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from pathlib import Path

    from pytola.dev.pypack.models.project import Project


class ProjectCache:
    """缓存项目解析结果以提高性能.

    使用LRU缓存策略, 避免重复解析pyproject.toml文件.
    """

    def __init__(self, max_size: int = 50, ttl_seconds: int = 300) -> None:
        self.max_size = max_size
        self.ttl_seconds = ttl_seconds
        self._cache: dict[Path, tuple[Project, float]] = {}
        self._access_times: dict[Path, float] = {}

    def get(self, pyproject_path: Path) -> Project | None:
        """获取缓存的项目对象.

        Args:
            pyproject_path: pyproject.toml文件路径

        Returns
        -------
            缓存的Project对象, 如果不存在或过期则返回None
        """
        if pyproject_path not in self._cache:
            return None

        project, timestamp = self._cache[pyproject_path]
        access_time = self._access_times[pyproject_path]

        # 检查时间戳和访问时间是否过期
        current_time = time.time()
        if current_time - timestamp > self.ttl_seconds or current_time - access_time > self.ttl_seconds:
            del self._cache[pyproject_path]
            del self._access_times[pyproject_path]
            return None

        # 更新访问时间
        self._access_times[pyproject_path] = current_time
        return project

    def put(self, pyproject_path: Path, project: Project) -> None:
        """存储项目对象到缓存.

        Args:
            pyproject_path: pyproject.toml文件路径
            project: 要缓存的Project对象
        """
        current_time = time.time()

        # 如果缓存已满, 移除最久未使用的项
        if len(self._cache) >= self.max_size:
            oldest_key = min(
                self._access_times.keys(),
                key=lambda k: self._access_times[k],
            )
            del self._cache[oldest_key]
            del self._access_times[oldest_key]

        self._cache[pyproject_path] = (project, current_time)
        self._access_times[pyproject_path] = current_time

    def invalidate(self, pyproject_path: Path) -> None:
        """使指定路径的缓存失效.

        Args:
            pyproject_path: 要使缓存失效的路径
        """
        if pyproject_path in self._cache:
            del self._cache[pyproject_path]
        if pyproject_path in self._access_times:
            del self._access_times[pyproject_path]

    @property
    def size(self) -> int:
        """返回当前缓存大小."""
        return len(self._cache)

    def clear(self) -> None:
        """清空所有缓存."""
        self._cache.clear()
        self._access_times.clear()
