"""Tests for DPE configuration models."""

import pytest
from pydantic import ValidationError

from dpe.models.config import BudgetLimits, DPEConfig, ThrottleBehavior


class TestBudgetLimits:
    def test_defaults(self) -> None:
        bl = BudgetLimits()
        assert bl.max_total_calls == 10
        assert bl.max_premium_calls == 6
        assert bl.max_wall_time_seconds == 900
        assert bl.max_critique_rounds == 2
        assert bl.throttle_behavior == ThrottleBehavior.ABORT

    def test_reject_zero_total_calls(self) -> None:
        with pytest.raises(ValidationError):
            BudgetLimits(max_total_calls=0)

    def test_reject_negative_wall_time(self) -> None:
        with pytest.raises(ValidationError):
            BudgetLimits(max_wall_time_seconds=-1)

    def test_critique_rounds_capped(self) -> None:
        with pytest.raises(ValidationError):
            BudgetLimits(max_critique_rounds=5)

    def test_all_throttle_behaviors(self) -> None:
        for behavior in ThrottleBehavior:
            bl = BudgetLimits(throttle_behavior=behavior)
            assert bl.throttle_behavior == behavior


class TestDPEConfig:
    def test_default_config(self) -> None:
        cfg = DPEConfig()
        assert cfg.simulation_mode is False
        assert cfg.budget.max_total_calls == 10

    def test_config_hash_deterministic(self) -> None:
        cfg = DPEConfig()
        assert cfg.config_hash() == cfg.config_hash()

    def test_config_hash_changes_on_mutation(self) -> None:
        cfg_a = DPEConfig()
        cfg_b = DPEConfig(simulation_mode=True)
        assert cfg_a.config_hash() != cfg_b.config_hash()

    def test_config_hash_is_sha256(self) -> None:
        cfg = DPEConfig()
        h = cfg.config_hash()
        assert len(h) == 64
        assert all(c in "0123456789abcdef" for c in h)

    def test_simulation_mode_override(self) -> None:
        cfg = DPEConfig(simulation_mode=True)
        assert cfg.simulation_mode is True

    def test_custom_budget(self) -> None:
        cfg = DPEConfig(budget=BudgetLimits(max_total_calls=5, max_premium_calls=2))
        assert cfg.budget.max_total_calls == 5
        assert cfg.budget.max_premium_calls == 2
