from vcti.config.field import _MISSING_TYPE, MISSING
from vcti.config.resolve import resolve_value


class TestResolveValue:
    """Tests for resolve_value."""

    def test_first_non_none_wins(self):
        assert resolve_value("a", "b", default="c") == "a"

    def test_skips_none(self):
        assert resolve_value(None, "b", default="c") == "b"

    def test_all_none_returns_default(self):
        assert resolve_value(None, None, default="fallback") == "fallback"

    def test_no_values_returns_default(self):
        assert resolve_value(default="fallback") == "fallback"

    def test_no_default_returns_none(self):
        assert resolve_value(None, None) is None

    def test_single_value(self):
        assert resolve_value("only") == "only"

    def test_type_preservation_int(self):
        result = resolve_value(None, 42, default=0)
        assert result == 42
        assert isinstance(result, int)

    def test_type_preservation_bool(self):
        result = resolve_value(None, None, default=False)
        assert result is False

    def test_many_candidates(self):
        assert resolve_value(None, None, None, None, "found", None, default="x") == "found"

    def test_zero_is_not_none(self):
        """0, False, and '' are valid non-None values."""
        assert resolve_value(0, default=42) == 0
        assert resolve_value(False, default=True) is False
        assert resolve_value("", default="fallback") == ""

    def test_missing_default_passes_through(self):
        """When default=MISSING and all values are None, returns MISSING.

        This is the contract ConfigSchema.load() relies on to detect
        required fields with no value from any source.
        """
        result = resolve_value(None, None, default=MISSING)
        assert isinstance(result, _MISSING_TYPE)
        assert result is MISSING
