"""Tests for agent error classification and message lookup."""

import anthropic
import httpx
import pydantic_ai.exceptions
import pytest

from app.agents.errors import ERROR_MESSAGES, classify_error, get_error_message

# ---------------------------------------------------------------------------
# classify_error
# ---------------------------------------------------------------------------

_MOCK_REQUEST = httpx.Request(method="GET", url="https://api.anthropic.com/v1/messages")
_MOCK_429 = httpx.Response(status_code=429, request=_MOCK_REQUEST)
_MOCK_400 = httpx.Response(status_code=400, request=_MOCK_REQUEST)


class TestClassifyError:
    def test_rate_limit(self):
        exc = anthropic.RateLimitError(message="rate limited", response=_MOCK_429, body=None)
        assert classify_error(exc) == "rate_limit"

    def test_bad_request_context_keyword(self):
        exc = anthropic.BadRequestError(
            message="prompt is too long: context window exceeded",
            response=_MOCK_400,
            body=None,
        )
        assert classify_error(exc) == "context_overflow"

    def test_bad_request_token_keyword(self):
        exc = anthropic.BadRequestError(
            message="Too many input tokens", response=_MOCK_400, body=None
        )
        assert classify_error(exc) == "context_overflow"

    def test_bad_request_without_keywords(self):
        exc = anthropic.BadRequestError(
            message="invalid model parameter", response=_MOCK_400, body=None
        )
        assert classify_error(exc) == "unknown"

    def test_connect_error(self):
        exc = httpx.ConnectError("connection refused")
        assert classify_error(exc) == "service_unavailable"

    def test_timeout_exception(self):
        exc = httpx.ReadTimeout("read timed out")
        assert classify_error(exc) == "service_unavailable"

    def test_unexpected_model_behavior(self):
        exc = pydantic_ai.exceptions.UnexpectedModelBehavior("bad tool call")
        assert classify_error(exc) == "tool_failure"

    def test_generic_exception(self):
        assert classify_error(Exception("boom")) == "unknown"

    def test_value_error(self):
        assert classify_error(ValueError("nope")) == "unknown"


# ---------------------------------------------------------------------------
# get_error_message
# ---------------------------------------------------------------------------


class TestGetErrorMessage:
    @pytest.mark.parametrize("code", list(ERROR_MESSAGES))
    def test_nl_messages(self, code: str):
        msg = get_error_message(code, "nl")
        assert msg == ERROR_MESSAGES[code]["nl"]

    @pytest.mark.parametrize("code", list(ERROR_MESSAGES))
    def test_en_messages(self, code: str):
        msg = get_error_message(code, "en")
        assert msg == ERROR_MESSAGES[code]["en"]

    def test_unknown_language_falls_back_to_nl(self):
        msg = get_error_message("rate_limit", "fr")
        assert msg == ERROR_MESSAGES["rate_limit"]["nl"]

    def test_unknown_code_falls_back_to_unknown(self):
        msg = get_error_message("nonexistent_code", "en")
        assert msg == ERROR_MESSAGES["unknown"]["en"]

    def test_unknown_code_and_unknown_language(self):
        msg = get_error_message("nonexistent_code", "fr")
        assert msg == ERROR_MESSAGES["unknown"]["nl"]
