import pytest

from veritell_langchain.client import VeritellClient
from veritell_langchain.errors import (
    RateLimitedError,
    ServiceUnavailableError,
    VeritellAuthError,
    VeritellTimeoutError,
)


def test_c14_fail_open_true_returns_default_on_429():
    client = VeritellClient(base_url="http://test", api_key="test", fail_open=True)

    def _fake_post(*args, **kwargs):
        raise RateLimitedError(status=429, error="rate_limited", message="Too many requests")

    client._post_json = _fake_post  # type: ignore[attr-defined]

    result = client.evaluate(prompt="p", model_output="o")

    assert result is not None
    assert result.risk_label in ("unknown", "skipped", "skipped_unknown")
    assert getattr(result, "extra", {}).get("reason") == "rate_limited"


def test_c14_fail_open_true_returns_default_on_503():
    client = VeritellClient(base_url="http://test", api_key="test", fail_open=True)

    def _fake_post(*args, **kwargs):
        raise ServiceUnavailableError(status=503, error="service_unavailable", message="Down")

    client._post_json = _fake_post  # type: ignore[attr-defined]

    result = client.evaluate(prompt="p", model_output="o")

    assert result is not None
    assert result.risk_label in ("unknown", "skipped", "skipped_unknown")
    assert getattr(result, "extra", {}).get("reason") == "service_unavailable"


def test_c14_fail_open_true_returns_default_on_timeout():
    client = VeritellClient(base_url="http://test", api_key="test", fail_open=True)

    def _fake_post(*args, **kwargs):
        raise VeritellTimeoutError(message="Timed out")

    client._post_json = _fake_post  # type: ignore[attr-defined]

    result = client.evaluate(prompt="p", model_output="o")

    assert result is not None
    assert result.risk_label in ("unknown", "skipped", "skipped_unknown")
    assert getattr(result, "extra", {}).get("reason") == "timeout"


def test_c14_fail_open_false_raises_on_429():
    client = VeritellClient(base_url="http://test", api_key="test", fail_open=False)

    def _fake_post(*args, **kwargs):
        raise RateLimitedError(status=429, error="rate_limited", message="Too many requests")

    client._post_json = _fake_post  # type: ignore[attr-defined]

    with pytest.raises(RateLimitedError):
        client.evaluate(prompt="p", model_output="o")


def test_c14_fail_open_true_does_not_swallow_auth_errors():
    client = VeritellClient(base_url="http://test", api_key="test", fail_open=True)

    def _fake_post(*args, **kwargs):
        raise VeritellAuthError(status=401, error="invalid_api_key", message="Nope")

    client._post_json = _fake_post  # type: ignore[attr-defined]

    with pytest.raises(VeritellAuthError):
        client.evaluate(prompt="p", model_output="o")
