"""Pure logic of the Jev ranker: how `Ranking.order` applies the cut, breaks
ties and places failed chunks, and what the TypeSafe settings default to.
Nothing here calls the API, so nothing here is evidence that ranking works."""

import pytest

from quber.playground.ranking import ChunkScore, PageScore, Ranking
from quber.settings import PlaygroundSettings, TypeSafeSettings


@pytest.fixture(autouse=True)
def no_dotenv(monkeypatch: pytest.MonkeyPatch, tmp_path):
    """Settings read `.env` from the working directory; an empty one keeps the
    developer's real file out of these defaults."""
    monkeypatch.chdir(tmp_path)


def chunk(index, score=None, error=None):
    return ChunkScore(index=index, chunk_id=f"c{index}", page=0, grade=None, score=score, error=error)


def ranking(scores, cut=1.4):
    return Ranking(pages=[PageScore(page=0, relevant=True)], scores=scores, grade_cut=cut)


def test_order_keeps_chunks_at_or_above_the_cut_highest_first():
    r = ranking([chunk(0, 0.9), chunk(1, 2.1), chunk(2, 1.4), chunk(3, 2.7)])
    assert r.order() == [3, 1, 2]
    assert r.cleared() == 3


def test_order_keeps_candidate_order_on_ties():
    r = ranking([chunk(0, 2.0), chunk(1, 2.0), chunk(2, 2.0)])
    assert r.order() == [0, 1, 2]


def test_failed_chunks_follow_the_graded_ones_in_candidate_order():
    r = ranking(
        [chunk(0, error="503: boom"), chunk(1, 2.5), chunk(2, error="ModelAPIError: x"), chunk(3, 1.0)]
    )
    assert r.order() == [1, 0, 2]
    assert r.cleared() == 1


def test_nothing_clears_the_cut_gives_an_empty_order():
    r = ranking([chunk(0, 0.2), chunk(1, 1.39)])
    assert r.order() == []


def test_typesafe_settings_defaults(monkeypatch: pytest.MonkeyPatch):
    for var in (
        "TYPESAFE_API_KEY",
        "QUBER_TYPESAFE_MODEL",
        "QUBER_TYPESAFE_GRADE_CUT",
        "QUBER_TYPESAFE_CONCURRENCY",
    ):
        monkeypatch.delenv(var, raising=False)
    ts = TypeSafeSettings()
    assert ts.api_key is None
    assert ts.model == "jev-1.13.0"
    assert ts.grade_cut == 1.4
    assert ts.concurrency == 32
    assert ts.max_retries == 2
    assert ts.timeout_seconds == 60.0


def test_typesafe_settings_read_the_environment(monkeypatch: pytest.MonkeyPatch):
    monkeypatch.setenv("TYPESAFE_API_KEY", "k")
    monkeypatch.setenv("QUBER_TYPESAFE_GRADE_CUT", "1.5")
    ts = TypeSafeSettings()
    assert ts.api_key == "k"
    assert ts.grade_cut == 1.5


def test_ranker_defaults_to_haiku_and_refuses_other_names(monkeypatch: pytest.MonkeyPatch):
    monkeypatch.delenv("QUBER_PLAYGROUND_RANKER", raising=False)
    assert PlaygroundSettings().ranker == "haiku"
    monkeypatch.setenv("QUBER_PLAYGROUND_RANKER", "jev")
    assert PlaygroundSettings().ranker == "jev"
    monkeypatch.setenv("QUBER_PLAYGROUND_RANKER", "sonnet")
    with pytest.raises(ValueError):
        PlaygroundSettings()
