"""DRS v1.4 API client."""

from __future__ import annotations

from typing import Any

from ai4gh.core.client import GA4GHClient
from ai4gh.specs.drs.models import DRSURI, AccessURL, DRSObject


class DRSClient(GA4GHClient):
    """Client for the GA4GH Data Repository Service (DRS) v1.4.

    DRS provides a generic interface to data repositories, mapping
    logical IDs to physical access methods for retrieving data objects.
    """

    spec_name = "drs"
    spec_version = "1.4.0"
    base_path = "/ga4gh/drs/v1"

    async def get_object(
        self,
        object_id: str,
        *,
        expand: bool = False,
    ) -> DRSObject:
        """Get a DRS object by ID.

        Args:
            object_id: The DRS object identifier.
            expand: If true, expand nested bundle contents.

        Returns:
            The DRS object metadata.
        """
        params: dict[str, Any] = {}
        if expand:
            params["expand"] = "true"
        data = await self._request("GET", f"/objects/{object_id}", params=params or None)
        return DRSObject.model_validate(data)

    async def get_access_url(
        self,
        object_id: str,
        access_id: str,
    ) -> AccessURL:
        """Get an access URL for a DRS object.

        Args:
            object_id: The DRS object identifier.
            access_id: The access method identifier.

        Returns:
            An AccessURL with the download URL and optional headers.
        """
        data = await self._request("GET", f"/objects/{object_id}/access/{access_id}")
        return AccessURL.model_validate(data)

    async def post_object(
        self,
        object_id: str,
        *,
        passports: list[str] | None = None,
        expand: bool = False,
    ) -> DRSObject:
        """Get a DRS object using Passport authentication (POST).

        Args:
            object_id: The DRS object identifier.
            passports: List of GA4GH Passport JWT tokens.
            expand: If true, expand nested bundle contents.

        Returns:
            The DRS object metadata.
        """
        body: dict[str, Any] = {}
        if passports:
            body["passports"] = passports
        params: dict[str, Any] = {}
        if expand:
            params["expand"] = "true"
        data = await self._request(
            "POST",
            f"/objects/{object_id}",
            json=body or None,
            params=params or None,
        )
        return DRSObject.model_validate(data)

    @classmethod
    def from_uri(
        cls,
        drs_uri: str | DRSURI,
        **kwargs: Any,
    ) -> DRSClient:
        """Create a DRS client from a DRS URI.

        Args:
            drs_uri: A DRS URI (drs://host/id).
            **kwargs: Additional arguments for GA4GHClient.

        Returns:
            A DRSClient configured for the URI's host.
        """
        if isinstance(drs_uri, str):
            drs_uri = DRSURI(drs_uri)
        return cls(base_url=drs_uri.base_url, **kwargs)
