"""High-value tests for metrics/pricing module.

Covers gaps in PricingCache and CostCalculator not addressed by existing tests:
- Cache overwrite behavior, TTL-based expiration
- CostCalculator.calculate_cost_sync exact arithmetic and edge cases
"""

import pytest

from local_deep_research.metrics.pricing.pricing_cache import PricingCache
from local_deep_research.metrics.pricing.cost_calculator import CostCalculator


class TestPricingCacheOverwrite:
    """Test cache key overwrite behavior."""

    def test_set_overwrites_existing_key_data(self):
        """Overwriting a key replaces the data."""
        cache = PricingCache(cache_ttl=3600)
        cache.set("k", {"old": True})
        cache.set("k", {"new": True})
        assert cache.get("k") == {"new": True}

    def test_get_with_primitive_value_round_trips(self):
        """Non-dict values (strings) are preserved through set/get."""
        cache = PricingCache(cache_ttl=3600)
        cache.set("k", "hello")
        assert cache.get("k") == "hello"


class TestPricingCacheTTLExpiration:
    """Test TTL-based expiration via cachetools.TTLCache."""

    def test_zero_ttl_makes_every_entry_expired(self):
        """With cache_ttl=0, entries are immediately expired."""
        cache = PricingCache(cache_ttl=0)
        cache.set("k", "data")
        # Give a tiny amount of time for clock to advance
        assert cache.get("k") is None

    def test_clear_then_stats_all_zeros(self):
        """After clear(), stats show zero entries."""
        cache = PricingCache(cache_ttl=3600)
        cache.set("a", 1)
        cache.set("b", 2)
        cache.clear()
        stats = cache.get_cache_stats()
        assert stats["total_entries"] == 0


class TestCostCalculatorSync:
    """Test CostCalculator.calculate_cost_sync."""

    def test_unknown_model_returns_zero_cost(self):
        """Unknown model returns zero cost with error message."""
        calc = CostCalculator()
        result = calc.calculate_cost_sync("totally-unknown-model-xyz", 500, 500)
        assert result["prompt_cost"] == 0.0
        assert result["completion_cost"] == 0.0
        assert result["total_cost"] == 0.0
        assert result["pricing_used"] is None
        assert "error" in result

    def test_prompt_plus_completion_equals_total(self):
        """prompt_cost + completion_cost == total_cost for known models."""
        calc = CostCalculator()
        result = calc.calculate_cost_sync("gpt-4", 3000, 1500)
        if result["pricing_used"] is not None:
            assert (
                abs(
                    (result["prompt_cost"] + result["completion_cost"])
                    - result["total_cost"]
                )
                < 1e-9
            )

    def test_zero_completion_tokens(self):
        """Zero completion tokens yields completion_cost == 0."""
        calc = CostCalculator()
        result = calc.calculate_cost_sync("gpt-4", 1000, 0)
        if result["pricing_used"] is not None:
            assert result["completion_cost"] == 0.0
            assert result["total_cost"] == result["prompt_cost"]

    def test_provider_prefixed_model_resolved(self):
        """Model with provider prefix (e.g. 'openai/gpt-4') is resolved."""
        calc = CostCalculator()
        result = calc.calculate_cost_sync("openai/gpt-4", 1000, 1000)
        # Should find gpt-4 via the split("/")[-1] fallback
        if result["pricing_used"] is not None:
            assert result["total_cost"] > 0.0

    def test_provider_prefix_unresolvable_returns_zero(self):
        """Unresolvable provider-prefixed model returns zero cost."""
        calc = CostCalculator()
        result = calc.calculate_cost_sync(
            "fakeprovider/no-such-model", 500, 500
        )
        assert result["total_cost"] == 0.0
        assert result["pricing_used"] is None

    def test_cache_used_over_static_pricing(self):
        """Pre-seeded cache values are used instead of static pricing."""
        calc = CostCalculator()
        custom_pricing = {"prompt": 0.1, "completion": 0.2}
        calc.cache.set_model_pricing("my-custom-model", custom_pricing)
        result = calc.calculate_cost_sync("my-custom-model", 1000, 1000)
        assert result["pricing_used"] == custom_pricing
        assert result["prompt_cost"] == pytest.approx(0.1)
        assert result["completion_cost"] == pytest.approx(0.2)

    def test_success_result_has_expected_keys(self):
        """Successful result has exactly 4 keys (no error key)."""
        calc = CostCalculator()
        calc.cache.set_model_pricing(
            "test-model", {"prompt": 0.01, "completion": 0.02}
        )
        result = calc.calculate_cost_sync("test-model", 100, 100)
        assert set(result.keys()) == {
            "prompt_cost",
            "completion_cost",
            "total_cost",
            "pricing_used",
        }
