"""Tests for eval-output scoring contract (scoring.py)."""

import pytest

from clawbench.scoring import (
    InvalidEvalOutput,
    extract_score,
    validate_side_info,
)


class TestExtractScore:
    def test_score_key(self):
        assert extract_score({"score": 0.8, "other": 0.5}) == 0.8

    def test_reward_key_fallback(self):
        assert extract_score({"reward": 0.7, "other": 0.3}) == 0.7

    def test_score_preferred_over_reward(self):
        assert extract_score({"score": 0.9, "reward": 0.1}) == 0.9

    def test_non_dict_raises(self):
        with pytest.raises(InvalidEvalOutput, match="must be a dict"):
            extract_score("not a dict")

    def test_none_raises(self):
        with pytest.raises(InvalidEvalOutput, match="must be a dict"):
            extract_score(None)

    def test_no_score_or_reward_key(self):
        with pytest.raises(InvalidEvalOutput, match="neither 'score' nor 'reward'"):
            extract_score({"accuracy": 0.9})

    def test_non_numeric_value_raises(self):
        with pytest.raises(InvalidEvalOutput, match="must be numeric"):
            extract_score({"score": "high"})

    def test_non_numeric_other_value_raises(self):
        with pytest.raises(InvalidEvalOutput, match="must be numeric"):
            extract_score({"score": 0.5, "detail": "text"})

    def test_int_score(self):
        assert extract_score({"score": 1}) == 1.0

    def test_zero_score(self):
        assert extract_score({"score": 0.0}) == 0.0


class TestValidateSideInfo:
    def test_valid(self):
        si = {"Feedback": {"Status": "completed"}, "Generated Outputs": {}}
        assert validate_side_info(si, "test") == []

    def test_non_dict(self):
        warnings = validate_side_info("bad", "test")
        assert len(warnings) == 1
        assert "not a dict" in warnings[0]

    def test_bad_feedback(self):
        warnings = validate_side_info({"Feedback": "string"}, "test")
        assert any("Feedback" in w for w in warnings)

    def test_bad_generated_outputs(self):
        warnings = validate_side_info({"Generated Outputs": 42}, "test")
        assert any("Generated Outputs" in w for w in warnings)
