"""Tests for DUO models."""

from __future__ import annotations

from ai4gh.specs.duo.models import (
    CompatibilityResult,
    DataUseCondition,
    DUOModifier,
    DUOTerm,
    ResearchPurpose,
)


class TestDUOModifier:
    def test_enum_values(self) -> None:
        assert DUOModifier.NO_RESTRICTION == "DUO:0000004"
        assert DUOModifier.GENERAL_RESEARCH_USE == "DUO:0000042"
        assert DUOModifier.DISEASE_SPECIFIC == "DUO:0000007"
        assert DUOModifier.NOT_FOR_PROFIT == "DUO:0000018"
        assert DUOModifier.NON_COMMERCIAL == "DUO:0000046"

    def test_from_string(self) -> None:
        assert DUOModifier("DUO:0000004") is DUOModifier.NO_RESTRICTION


class TestDUOTerm:
    def test_minimal(self) -> None:
        term = DUOTerm(id="DUO:0000004")
        assert term.id == "DUO:0000004"
        assert term.label is None

    def test_full(self) -> None:
        term = DUOTerm(
            id="DUO:0000007",
            label="disease specific research",
            description="Use is limited to research on the specified disease",
            shorthand="DS",
        )
        assert term.label == "disease specific research"

    def test_with_modifiers(self) -> None:
        term = DUOTerm(
            id="DUO:0000007",
            label="disease specific",
            modifiers=[DUOTerm(id="DUO:0000018", label="not-for-profit only")],
        )
        assert len(term.modifiers) == 1


class TestDataUseCondition:
    def test_minimal(self) -> None:
        cond = DataUseCondition(code="DUO:0000004")
        assert cond.code == "DUO:0000004"
        assert cond.disease_id is None

    def test_disease_specific(self) -> None:
        cond = DataUseCondition(
            code="DUO:0000007",
            label="disease specific",
            disease_id="MONDO:0005015",
        )
        assert cond.disease_id == "MONDO:0005015"

    def test_institution_specific(self) -> None:
        cond = DataUseCondition(
            code="DUO:0000028",
            institution="Broad Institute",
        )
        assert cond.institution == "Broad Institute"


class TestResearchPurpose:
    def test_minimal(self) -> None:
        purpose = ResearchPurpose(codes=["DUO:0000042"])
        assert purpose.is_for_profit is False

    def test_full(self) -> None:
        purpose = ResearchPurpose(
            codes=["DUO:0000007"],
            is_for_profit=False,
            disease_id="MONDO:0005015",
            institution="MIT",
            project="Diabetes Study",
        )
        assert purpose.disease_id == "MONDO:0005015"


class TestCompatibilityResult:
    def test_compatible(self) -> None:
        result = CompatibilityResult(
            compatible=True,
            reason="All conditions satisfied",
            matched_conditions=[DataUseCondition(code="DUO:0000004")],
        )
        assert result.compatible is True
        assert len(result.matched_conditions) == 1

    def test_incompatible(self) -> None:
        result = CompatibilityResult(
            compatible=False,
            reason="Blocking conditions found",
            blocking_conditions=[DataUseCondition(code="DUO:0000018")],
        )
        assert result.compatible is False
        assert len(result.blocking_conditions) == 1
