"""High-value edge case tests for web/warning_checks module.

Covers gaps not addressed by existing tests:
- check_model_mismatch with various 70b model name patterns
- check_model_mismatch dismissed state
- check_high_context with exact boundary values
- check_context_below_history with single-record percentile
- check_context_truncation_history with zero/negative counts
"""

from unittest.mock import MagicMock

from local_deep_research.web.warning_checks.hardware import (
    check_high_context,
    check_model_mismatch,
    LOCAL_PROVIDERS,
)
from local_deep_research.web.warning_checks.context import (
    check_context_below_history,
    check_context_truncation_history,
)


class TestCheckModelMismatchEdgeCases:
    """Edge cases for check_model_mismatch."""

    def test_70b_at_end_of_name(self):
        """Detects 70b at the end of model name."""
        result = check_model_mismatch("ollama", "llama3.1-70b", 16384, False)
        assert result is not None
        assert result["type"] == "model_mismatch"

    def test_70b_in_middle_of_name(self):
        """Detects 70b embedded in model name."""
        result = check_model_mismatch(
            "ollama", "meta-llama-70b-instruct", 16384, False
        )
        assert result is not None

    def test_70B_uppercase(self):
        """Case-insensitive detection of 70B."""
        result = check_model_mismatch("ollama", "Llama-70B-Chat", 16384, False)
        assert result is not None

    def test_no_warning_for_7b_model(self):
        """7b model doesn't match the 70b pattern."""
        result = check_model_mismatch("ollama", "llama3-7b", 16384, False)
        assert result is None

    def test_no_warning_for_170b_model(self):
        """170b still contains '70b' substring, so it would match."""
        result = check_model_mismatch("ollama", "model-170b", 16384, False)
        # "170b" contains "70b" so it matches
        assert result is not None

    def test_dismissed_returns_none(self):
        """Dismissed warning returns None."""
        result = check_model_mismatch("ollama", "llama-70b", 16384, True)
        assert result is None

    def test_none_model_returns_none(self):
        """None model string returns None."""
        result = check_model_mismatch("ollama", None, 16384, False)
        assert result is None

    def test_empty_model_returns_none(self):
        """Empty model string returns None."""
        result = check_model_mismatch("ollama", "", 16384, False)
        assert result is None

    def test_model_name_in_message(self):
        """Warning message includes the model name."""
        result = check_model_mismatch(
            "ollama", "llama3-70b-instruct", 16384, False
        )
        assert "llama3-70b-instruct" in result["message"]

    def test_context_in_message(self):
        """Warning message includes the context size."""
        result = check_model_mismatch("ollama", "llama-70b", 32768, False)
        assert "32,768" in result["message"]

    def test_warning_dict_structure(self):
        """Warning dict has all expected keys."""
        result = check_model_mismatch("ollama", "llama-70b", 16384, False)
        expected_keys = {"type", "icon", "title", "message", "dismissKey"}
        assert set(result.keys()) == expected_keys


class TestCheckHighContextEdgeCases:
    """Additional edge cases for check_high_context."""

    def test_all_local_providers_trigger_at_16384(self):
        """All LOCAL_PROVIDERS trigger warning at high context."""
        for provider in LOCAL_PROVIDERS:
            result = check_high_context(provider, 16384, False)
            assert result is not None, f"{provider} should trigger warning"

    def test_non_local_provider_never_triggers(self):
        """Non-local providers never trigger, even with very high context."""
        for provider in ["openai", "anthropic", "google", "azure"]:
            result = check_high_context(provider, 1000000, False)
            assert result is None, f"{provider} should not trigger warning"

    def test_context_value_in_message(self):
        """Warning message includes formatted context value."""
        result = check_high_context("ollama", 16384, False)
        assert "16,384" in result["message"]

    def test_context_size_in_message(self):
        """Warning message includes context size."""
        result = check_high_context("ollama", 16384, False)
        assert "16,384" in result["message"]


class TestCheckContextBelowHistoryEdgeCases:
    """Edge cases for check_context_below_history."""

    def test_exactly_five_identical_records(self):
        """With 5 identical records, percentile equals that value."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.order_by.return_value.limit.return_value.all.return_value = (
            [(8192,)] * 5
        )

        # Context below that value should warn
        result = check_context_below_history(mock_session, 4096)
        assert result is not None
        assert result["type"] == "context_below_history"

    def test_at_exactly_min_safe_returns_none(self):
        """Context exactly at min_safe returns None (no warning)."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.order_by.return_value.limit.return_value.all.return_value = (
            [(8192,)] * 10
        )

        result = check_context_below_history(mock_session, 8192)
        assert result is None

    def test_warning_message_includes_context_values(self):
        """Warning message includes both current and min safe context."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.order_by.return_value.limit.return_value.all.return_value = (
            [(16384,)] * 10
        )

        result = check_context_below_history(mock_session, 4096)
        assert "4,096" in result["message"]
        assert "16,384" in result["message"]


class TestCheckContextTruncationHistoryEdgeCases:
    """Edge cases for check_context_truncation_history."""

    def test_zero_truncation_count_returns_none(self):
        """Zero truncation count means no warning."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.filter.return_value.scalar.return_value = 0

        result = check_context_truncation_history(mock_session, 8192)
        assert result is None

    def test_none_truncation_count_returns_none(self):
        """None truncation count returns None."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.filter.return_value.scalar.return_value = None

        result = check_context_truncation_history(mock_session, 8192)
        assert result is None

    def test_single_truncation_message(self):
        """Single truncation shows '1 time(s)' in message."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.filter.return_value.scalar.return_value = 1

        result = check_context_truncation_history(mock_session, 8192)
        assert result is not None
        assert "1 time(s)" in result["message"]

    def test_large_truncation_count(self):
        """Large truncation count is reported correctly."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.filter.return_value.scalar.return_value = 50

        result = check_context_truncation_history(mock_session, 4096)
        assert "50 time(s)" in result["message"]

    def test_warning_dict_structure(self):
        """Warning dict has all required keys (may carry optional enrichment fields)."""
        mock_session = MagicMock()
        mock_session.query.return_value.filter.return_value.filter.return_value.scalar.return_value = 5

        result = check_context_truncation_history(mock_session, 8192)
        required_keys = {"type", "icon", "title", "message", "dismissKey"}
        assert required_keys.issubset(set(result.keys()))
