"""Tests for DRS client."""

from __future__ import annotations

import pytest
from pytest_httpx import HTTPXMock

from ai4gh.specs.drs.client import DRSClient
from ai4gh.specs.drs.models import DRSURI

DRS_OBJECT_RESPONSE = {
    "id": "drs-obj-1",
    "self_uri": "drs://example.com/drs-obj-1",
    "size": 1024,
    "created_time": "2024-01-01T00:00:00Z",
    "checksums": [{"checksum": "abc123", "type": "md5"}],
    "access_methods": [
        {"type": "https", "access_id": "https-1"},
    ],
}


@pytest.fixture
def drs_client() -> DRSClient:
    return DRSClient(base_url="https://example.com")


class TestDRSClient:
    def test_spec_attrs(self) -> None:
        client = DRSClient(base_url="https://example.com")
        assert client.spec_name == "drs"
        assert client.spec_version == "1.4.0"
        assert client.base_path == "/ga4gh/drs/v1"

    def test_url(self) -> None:
        client = DRSClient(base_url="https://example.com")
        assert client.url == "https://example.com/ga4gh/drs/v1"

    async def test_get_object(self, drs_client: DRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/drs/v1/objects/drs-obj-1",
            json=DRS_OBJECT_RESPONSE,
        )
        obj = await drs_client.get_object("drs-obj-1")
        assert obj.id == "drs-obj-1"
        assert obj.size == 1024
        assert len(obj.checksums) == 1

    async def test_get_object_expand(self, drs_client: DRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(json=DRS_OBJECT_RESPONSE)
        obj = await drs_client.get_object("drs-obj-1", expand=True)
        assert obj.id == "drs-obj-1"
        request = httpx_mock.get_requests()[0]
        assert "expand=true" in str(request.url)

    async def test_get_access_url(self, drs_client: DRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/drs/v1/objects/drs-obj-1/access/https-1",
            json={"url": "https://download.example.com/file.bam"},
        )
        access_url = await drs_client.get_access_url("drs-obj-1", "https-1")
        assert access_url.url == "https://download.example.com/file.bam"

    async def test_post_object(self, drs_client: DRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(json=DRS_OBJECT_RESPONSE)
        obj = await drs_client.post_object(
            "drs-obj-1",
            passports=["jwt-token-1"],
        )
        assert obj.id == "drs-obj-1"

    async def test_post_object_expand(self, drs_client: DRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(json=DRS_OBJECT_RESPONSE)
        obj = await drs_client.post_object("drs-obj-1", expand=True)
        assert obj.id == "drs-obj-1"

    def test_from_uri_string(self) -> None:
        client = DRSClient.from_uri("drs://example.com/obj-1")
        assert client.url == "https://example.com/ga4gh/drs/v1"

    def test_from_uri_object(self) -> None:
        uri = DRSURI("drs://example.com/obj-1")
        client = DRSClient.from_uri(uri)
        assert client.url == "https://example.com/ga4gh/drs/v1"
