"""Tests for cache utilities."""

import time

import pytest

from ai_org.utils.cache import CacheManager


@pytest.mark.unit
class TestCacheManager:
    def test_init_custom_dir(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        assert cache.cache_dir == tmp_path / "cache"

    def test_init_ci_env(self, monkeypatch):
        monkeypatch.setenv("CI", "true")
        cache = CacheManager()
        assert ".augint" in str(cache.cache_dir) or "/tmp" in str(cache.cache_dir)

    def test_set_and_get(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        cache.set("ns", "key1", {"data": "value"})
        result = cache.get("ns", "key1")
        assert result == {"data": "value"}

    def test_get_missing_returns_none(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        assert cache.get("ns", "nonexistent") is None

    def test_get_expired_returns_none(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache", ttl=0)
        cache.set("ns", "key1", "value")
        time.sleep(0.1)
        assert cache.get("ns", "key1") is None

    def test_clear_namespace(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        cache.set("ns1", "key1", "value1")
        cache.set("ns2", "key2", "value2")
        cache.clear("ns1")
        assert cache.get("ns1", "key1") is None
        assert cache.get("ns2", "key2") == "value2"

    def test_clear_all(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        cache.set("ns1", "key1", "value1")
        cache.set("ns2", "key2", "value2")
        cache.clear()
        assert cache.get("ns1", "key1") is None
        assert cache.get("ns2", "key2") is None

    def test_get_or_compute_caches(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache")
        call_count = 0

        def compute():
            nonlocal call_count
            call_count += 1
            return "computed"

        result1 = cache.get_or_compute("ns", "key", compute)
        result2 = cache.get_or_compute("ns", "key", compute)
        assert result1 == "computed"
        assert result2 == "computed"
        assert call_count == 1

    def test_get_or_compute_recomputes_after_expiry(self, tmp_path):
        cache = CacheManager(cache_dir=tmp_path / "cache", ttl=0)
        call_count = 0

        def compute():
            nonlocal call_count
            call_count += 1
            return f"value-{call_count}"

        result1 = cache.get_or_compute("ns", "key", compute)
        time.sleep(0.1)
        result2 = cache.get_or_compute("ns", "key", compute)
        assert result1 == "value-1"
        assert result2 == "value-2"
        assert call_count == 2
