"""Tests for Beacon v2 models."""

from __future__ import annotations

from ai4gh.specs.beacon.models import (
    AlphanumericFilter,
    BeaconInfo,
    BeaconQuery,
    BeaconRequest,
    BeaconRequestMeta,
    BeaconResponse,
    BeaconResponseMeta,
    BeaconResultsetResponse,
    CustomFilter,
    FilteringTerm,
    Granularity,
    OntologyFilter,
    Operator,
    Similarity,
)


class TestGranularity:
    def test_values(self) -> None:
        assert Granularity.boolean.value == "boolean"
        assert Granularity.count.value == "count"
        assert Granularity.record.value == "record"


class TestOperator:
    def test_values(self) -> None:
        assert Operator.equals.value == "="
        assert Operator.less_than.value == "<"
        assert Operator.greater_than.value == ">"


class TestFilteringTerm:
    def test_basic(self) -> None:
        ft = FilteringTerm(id="HP:0001250")
        assert ft.id == "HP:0001250"
        assert ft.include_descendant_terms is True
        assert ft.similarity == Similarity.exact

    def test_custom_similarity(self) -> None:
        ft = FilteringTerm(id="HP:0001250", similarity=Similarity.high)
        assert ft.similarity == Similarity.high


class TestAlphanumericFilter:
    def test_basic(self) -> None:
        f = AlphanumericFilter(id="age", value=30)
        assert f.operator == Operator.equals
        assert f.value == 30

    def test_with_operator(self) -> None:
        f = AlphanumericFilter(id="age", operator=Operator.greater_than, value=18)
        assert f.operator == Operator.greater_than


class TestOntologyFilter:
    def test_basic(self) -> None:
        f = OntologyFilter(id="HP:0001250")
        assert f.include_descendant_terms is True


class TestCustomFilter:
    def test_basic(self) -> None:
        f = CustomFilter(id="custom:filter")
        assert f.id == "custom:filter"


class TestBeaconQuery:
    def test_defaults(self) -> None:
        q = BeaconQuery()
        assert q.filters is None
        assert q.test_mode is False

    def test_with_filters(self) -> None:
        q = BeaconQuery(
            filters=[FilteringTerm(id="HP:0001250")],
            test_mode=True,
        )
        assert q.filters is not None
        assert len(q.filters) == 1


class TestBeaconRequest:
    def test_defaults(self) -> None:
        r = BeaconRequest()
        assert r.meta.api_version == "v2.0.0"
        assert r.query.test_mode is False

    def test_custom(self) -> None:
        r = BeaconRequest(
            meta=BeaconRequestMeta(api_version="v2.1.0"),
            query=BeaconQuery(test_mode=True),
        )
        assert r.meta.api_version == "v2.1.0"
        assert r.query.test_mode is True


class TestBeaconResultsetResponse:
    def test_basic(self) -> None:
        rs = BeaconResultsetResponse(
            id="rs1",
            exists=True,
            results_count=5,
        )
        assert rs.id == "rs1"
        assert rs.exists is True
        assert rs.results_count == 5


class TestBeaconResponseMeta:
    def test_basic(self) -> None:
        m = BeaconResponseMeta(
            beacon_id="org.example.beacon",
            returned_granularity=Granularity.record,
        )
        assert m.beacon_id == "org.example.beacon"
        assert m.returned_granularity == Granularity.record


class TestBeaconResponse:
    def test_minimal(self) -> None:
        r = BeaconResponse()
        assert r.meta is None
        assert r.response is None

    def test_with_meta(self) -> None:
        r = BeaconResponse(
            meta=BeaconResponseMeta(beacon_id="test"),
            response_summary={"exists": True, "numTotalResults": 10},
        )
        assert r.meta is not None
        assert r.response_summary is not None


class TestBeaconInfo:
    def test_basic(self) -> None:
        info = BeaconInfo(
            id="org.example.beacon",
            name="Example Beacon",
            api_version="v2.0.0",
        )
        assert info.id == "org.example.beacon"
        assert info.name == "Example Beacon"

    def test_minimal(self) -> None:
        info = BeaconInfo(id="b1", name="B1")
        assert info.api_version is None
