"""Pydantic models for GA4GH Data Use Ontology (DUO).

DUO provides a standard vocabulary for describing data use conditions
and restrictions. This module models DUO terms and provides utilities
for checking compatibility between dataset conditions and researcher purposes.
"""

from __future__ import annotations

from enum import Enum

from ai4gh.core.types import GA4GHBase


class DUOModifier(str, Enum):
    """Common DUO modifier terms."""

    NO_RESTRICTION = "DUO:0000004"
    GENERAL_RESEARCH_USE = "DUO:0000042"
    HEALTH_MEDICAL_BIOMEDICAL = "DUO:0000006"
    DISEASE_SPECIFIC = "DUO:0000007"
    NOT_FOR_PROFIT = "DUO:0000018"
    NON_COMMERCIAL = "DUO:0000046"
    PUBLICATION_REQUIRED = "DUO:0000019"
    COLLABORATION_REQUIRED = "DUO:0000020"
    ETHICS_APPROVAL_REQUIRED = "DUO:0000021"
    GEOGRAPHICAL_RESTRICTION = "DUO:0000022"
    INSTITUTION_SPECIFIC = "DUO:0000028"
    PROJECT_SPECIFIC = "DUO:0000027"
    TIME_LIMIT = "DUO:0000025"
    USER_SPECIFIC = "DUO:0000026"
    RETURN_TO_DATABASE = "DUO:0000029"
    NO_GENERAL_METHODS = "DUO:0000015"
    GENETIC_STUDIES_ONLY = "DUO:0000016"
    POPULATION_ORIGINS = "DUO:0000011"


class DUOTerm(GA4GHBase):
    """A DUO term with optional modifiers."""

    id: str
    label: str | None = None
    description: str | None = None
    shorthand: str | None = None
    modifiers: list[DUOTerm] | None = None


class DataUseCondition(GA4GHBase):
    """A data use condition applied to a dataset."""

    code: str
    label: str | None = None
    description: str | None = None
    disease_id: str | None = None
    geographic_restriction: str | None = None
    institution: str | None = None
    project: str | None = None
    expiration_date: str | None = None


class ResearchPurpose(GA4GHBase):
    """A researcher's declared purpose for data access."""

    codes: list[str]
    is_for_profit: bool = False
    disease_id: str | None = None
    institution: str | None = None
    project: str | None = None


class CompatibilityResult(GA4GHBase):
    """Result of checking research purpose against data use conditions."""

    compatible: bool
    reason: str
    matched_conditions: list[DataUseCondition] | None = None
    blocking_conditions: list[DataUseCondition] | None = None
