"""Tests for metrics pricing_cache module."""

import time


from local_deep_research.metrics.pricing.pricing_cache import PricingCache


class TestPricingCacheInit:
    """Tests for PricingCache initialization."""

    def test_initializes_with_default_ttl(self):
        """Should initialize with default TTL of 3600 seconds."""
        cache = PricingCache()
        assert cache.cache_ttl == 3600

    def test_initializes_with_custom_ttl(self):
        """Should initialize with custom TTL."""
        cache = PricingCache(cache_ttl=7200)
        assert cache.cache_ttl == 7200

    def test_initializes_empty_cache(self):
        """Should initialize with empty in-memory cache."""
        cache = PricingCache()
        assert cache._cache == {}

    def test_cache_dir_is_deprecated(self):
        """Cache dir parameter should be ignored (deprecated)."""
        cache = PricingCache(cache_dir="/some/path")
        # Should not raise and should work normally
        assert cache._cache == {}


class TestPricingCacheGetSet:
    """Tests for PricingCache get/set methods."""

    def test_get_returns_none_for_missing_key(self):
        """Should return None for non-existent key."""
        cache = PricingCache()
        result = cache.get("nonexistent")
        assert result is None

    def test_set_stores_data_with_timestamp(self):
        """Should store data with timestamp."""
        cache = PricingCache()
        cache.set("test_key", {"value": 123})

        assert "test_key" in cache._cache
        assert cache._cache["test_key"]["data"] == {"value": 123}
        assert "timestamp" in cache._cache["test_key"]

    def test_get_returns_valid_data(self):
        """Should return data for valid key."""
        cache = PricingCache()
        cache.set("test_key", {"value": 456})

        result = cache.get("test_key")
        assert result == {"value": 456}

    def test_get_returns_none_for_expired_key(self):
        """Should return None and remove expired entries."""
        cache = PricingCache(cache_ttl=1)  # 1 second TTL
        cache.set("test_key", {"value": 789})

        # Wait for expiration
        time.sleep(1.1)

        result = cache.get("test_key")
        assert result is None
        assert "test_key" not in cache._cache


class TestPricingCacheModelPricing:
    """Tests for model pricing methods."""

    def test_get_model_pricing_returns_none_for_missing(self):
        """Should return None for missing model pricing."""
        cache = PricingCache()
        result = cache.get_model_pricing("gpt-4")
        assert result is None

    def test_set_model_pricing_stores_with_prefix(self):
        """Should store pricing with 'model:' prefix."""
        cache = PricingCache()
        pricing = {"prompt": 0.03, "completion": 0.06}
        cache.set_model_pricing("gpt-4", pricing)

        assert "model:gpt-4" in cache._cache
        assert cache._cache["model:gpt-4"]["data"] == pricing

    def test_get_model_pricing_retrieves_stored(self):
        """Should retrieve stored model pricing."""
        cache = PricingCache()
        pricing = {"prompt": 0.03, "completion": 0.06}
        cache.set_model_pricing("gpt-4", pricing)

        result = cache.get_model_pricing("gpt-4")
        assert result == pricing


class TestPricingCacheAllPricing:
    """Tests for all pricing methods."""

    def test_get_all_pricing_returns_none_when_not_set(self):
        """Should return None when all pricing not cached."""
        cache = PricingCache()
        result = cache.get_all_pricing()
        assert result is None

    def test_set_all_pricing_stores_data(self):
        """Should store all pricing data."""
        cache = PricingCache()
        all_pricing = {
            "gpt-4": {"prompt": 0.03, "completion": 0.06},
            "gpt-3.5-turbo": {"prompt": 0.001, "completion": 0.002},
        }
        cache.set_all_pricing(all_pricing)

        assert "all_models" in cache._cache
        assert cache._cache["all_models"]["data"] == all_pricing

    def test_get_all_pricing_retrieves_stored(self):
        """Should retrieve stored all pricing."""
        cache = PricingCache()
        all_pricing = {
            "gpt-4": {"prompt": 0.03, "completion": 0.06},
        }
        cache.set_all_pricing(all_pricing)

        result = cache.get_all_pricing()
        assert result == all_pricing


class TestPricingCacheClear:
    """Tests for cache clearing methods."""

    def test_clear_removes_all_entries(self):
        """Should remove all cache entries."""
        cache = PricingCache()
        cache.set("key1", "value1")
        cache.set("key2", "value2")

        cache.clear()

        assert cache._cache == {}

    def test_clear_expired_removes_only_expired(self):
        """Should remove only expired entries."""
        cache = PricingCache(cache_ttl=2)  # 2 second TTL
        cache.set("old_key", "old_value")

        # Wait for old entry to expire
        time.sleep(2.1)

        # Add new entry
        cache.set("new_key", "new_value")

        cache.clear_expired()

        assert "old_key" not in cache._cache
        assert "new_key" in cache._cache

    def test_clear_expired_handles_empty_cache(self):
        """Should handle empty cache without error."""
        cache = PricingCache()
        cache.clear_expired()  # Should not raise
        assert cache._cache == {}


class TestPricingCacheStats:
    """Tests for cache statistics."""

    def test_get_cache_stats_returns_correct_structure(self):
        """Should return stats with correct keys."""
        cache = PricingCache(cache_ttl=3600)
        stats = cache.get_cache_stats()

        assert "total_entries" in stats
        assert "expired_entries" in stats
        assert "valid_entries" in stats
        assert "cache_type" in stats
        assert "cache_ttl" in stats

    def test_get_cache_stats_counts_entries(self):
        """Should count total entries correctly."""
        cache = PricingCache()
        cache.set("key1", "value1")
        cache.set("key2", "value2")
        cache.set("key3", "value3")

        stats = cache.get_cache_stats()

        assert stats["total_entries"] == 3
        assert stats["valid_entries"] == 3
        assert stats["expired_entries"] == 0

    def test_get_cache_stats_counts_expired(self):
        """Should count expired entries correctly."""
        cache = PricingCache(cache_ttl=1)
        cache.set("key1", "value1")

        time.sleep(1.1)

        stats = cache.get_cache_stats()

        assert stats["total_entries"] == 1
        assert stats["expired_entries"] == 1
        assert stats["valid_entries"] == 0

    def test_get_cache_stats_shows_cache_type(self):
        """Should show in-memory cache type."""
        cache = PricingCache()
        stats = cache.get_cache_stats()

        assert stats["cache_type"] == "in-memory"

    def test_get_cache_stats_shows_ttl(self):
        """Should show configured TTL."""
        cache = PricingCache(cache_ttl=7200)
        stats = cache.get_cache_stats()

        assert stats["cache_ttl"] == 7200


class TestPricingCacheIsExpired:
    """Tests for _is_expired method."""

    def test_is_expired_returns_false_for_recent(self):
        """Should return False for recent timestamp."""
        cache = PricingCache(cache_ttl=3600)
        recent_time = time.time() - 100  # 100 seconds ago

        result = cache._is_expired(recent_time)

        assert result is False

    def test_is_expired_returns_true_for_old(self):
        """Should return True for old timestamp."""
        cache = PricingCache(cache_ttl=3600)
        old_time = time.time() - 4000  # 4000 seconds ago

        result = cache._is_expired(old_time)

        assert result is True

    def test_is_expired_boundary_condition(self):
        """Should handle boundary condition correctly."""
        cache = PricingCache(cache_ttl=100)
        boundary_time = time.time() - 100

        # At exactly TTL seconds, should be expired
        result = cache._is_expired(boundary_time)

        # This may be True or False depending on exact timing
        assert isinstance(result, bool)
