"""Pydantic models for GA4GH DRS v1.4."""

from __future__ import annotations

from datetime import datetime  # noqa: TC003 — needed at runtime by Pydantic
from enum import Enum
from urllib.parse import urlparse

from ai4gh.core.types import GA4GHBase


class AccessType(str, Enum):
    """DRS access method types."""

    s3 = "s3"
    gs = "gs"
    ftp = "ftp"
    gsiftp = "gsiftp"
    globus = "globus"
    htsget = "htsget"
    https = "https"
    file = "file"


class Checksum(GA4GHBase):
    """DRS checksum."""

    checksum: str
    type: str


class AccessURL(GA4GHBase):
    """DRS access URL."""

    url: str
    headers: list[str] | None = None


class DRSAccessMethod(GA4GHBase):
    """DRS access method."""

    type: AccessType
    access_url: AccessURL | None = None
    access_id: str | None = None
    cloud: str | None = None
    region: str | None = None
    available: bool | None = None


class ContentsObject(GA4GHBase):
    """DRS contents object (for bundles)."""

    name: str
    id: str | None = None
    drs_uri: list[str] | None = None
    contents: list[ContentsObject] | None = None


class DRSObject(GA4GHBase):
    """DRS object."""

    id: str
    self_uri: str
    size: int
    created_time: datetime
    updated_time: datetime | None = None
    version: str | None = None
    mime_type: str | None = None
    name: str | None = None
    checksums: list[Checksum]
    access_methods: list[DRSAccessMethod] | None = None
    contents: list[ContentsObject] | None = None
    description: str | None = None
    aliases: list[str] | None = None

    @property
    def is_bundle(self) -> bool:
        """Check if this DRS object is a bundle."""
        return self.contents is not None


class DRSURI:
    """Parser for DRS URIs (drs://host/id)."""

    def __init__(self, uri: str) -> None:
        if not uri.startswith("drs://"):
            raise ValueError(f"Invalid DRS URI: must start with drs:// (got {uri!r})")
        self._uri = uri
        parsed = urlparse(uri)
        self.host = parsed.hostname or ""
        self.id = parsed.path.lstrip("/")

    @property
    def base_url(self) -> str:
        """Convert to HTTPS base URL."""
        return f"https://{self.host}"

    def __str__(self) -> str:
        return self._uri

    def __repr__(self) -> str:
        return f"DRSURI({self._uri!r})"
