"""Tests for TimeRangeSpec and SignalSpec."""

import numpy as np
import pytest
from pydantic import ValidationError

from radiens_core.models.dataset import TimeRangeSpec, TrsMode


class TestTimeRangeSpec:
    def test_subset(self) -> None:
        spec = TimeRangeSpec.subset(0, 10)
        assert spec.mode == TrsMode.SUBSET
        assert spec.start == 0
        assert spec.end == 10

    def test_subset_invalid(self) -> None:
        with pytest.raises(ValueError, match="must be greater"):
            TimeRangeSpec.subset(10, 5)

    def test_lookback(self) -> None:
        spec = TimeRangeSpec.lookback(5.0)
        assert spec.mode == TrsMode.FROM_HEAD
        assert spec.start == 5.0
        assert spec.end is None

    def test_lookback_invalid(self) -> None:
        with pytest.raises(ValueError, match="positive"):
            TimeRangeSpec.lookback(-1.0)

    def test_to_head(self) -> None:
        spec = TimeRangeSpec.to_head(10.0)
        assert spec.mode == TrsMode.TO_HEAD
        assert spec.start == 10.0

    def test_full(self) -> None:
        spec = TimeRangeSpec.full()
        assert spec.is_full()
        assert spec.mode == TrsMode.SUBSET

    def test_from_list_subset(self) -> None:
        spec = TimeRangeSpec.from_list([0, 10])
        assert spec.mode == TrsMode.SUBSET
        assert spec.start == 0.0
        assert spec.end == 10.0

    def test_from_list_lookback(self) -> None:
        spec = TimeRangeSpec.from_list([5.0, float("nan")])
        assert spec.mode == TrsMode.FROM_HEAD

    def test_to_array_subset(self) -> None:
        spec = TimeRangeSpec.subset(0, 10)
        arr = spec.to_array()
        assert arr[0] == 0.0
        assert arr[1] == 10.0

    def test_to_array_lookback(self) -> None:
        spec = TimeRangeSpec.lookback(5.0)
        arr = spec.to_array()
        assert arr[0] == 5.0
        assert np.isnan(arr[1])

    def test_to_array_full_raises(self) -> None:
        with pytest.raises(ValueError, match="full"):
            TimeRangeSpec.full().to_array()

    def test_duration_subset(self) -> None:
        spec = TimeRangeSpec.subset(5, 15)
        assert spec.duration == 10.0

    def test_duration_lookback(self) -> None:
        spec = TimeRangeSpec.lookback(5.0)
        assert spec.duration == 5.0

    def test_duration_full(self) -> None:
        assert TimeRangeSpec.full().duration is None

    def test_repr_subset(self) -> None:
        assert "subset" in repr(TimeRangeSpec.subset(0, 10))

    def test_repr_lookback(self) -> None:
        assert "lookback" in repr(TimeRangeSpec.lookback(5.0))

    def test_repr_full(self) -> None:
        assert "full" in repr(TimeRangeSpec.full())

    def test_frozen(self) -> None:
        spec = TimeRangeSpec.subset(0, 10)
        with pytest.raises(ValidationError):
            spec.start = 5.0  # type: ignore[misc]
