"""Tests for TRS client."""

from __future__ import annotations

import pytest
from pytest_httpx import HTTPXMock

from ai4gh.specs.trs.client import TRSClient
from ai4gh.specs.trs.models import DescriptorType


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


class TestTRSClient:
    def test_spec_attrs(self) -> None:
        client = TRSClient(base_url="https://example.com")
        assert client.spec_name == "trs"
        assert client.spec_version == "2.0.1"
        assert client.base_path == "/ga4gh/trs/v2"

    def test_url(self) -> None:
        client = TRSClient(base_url="https://example.com")
        assert client.url == "https://example.com/ga4gh/trs/v2"

    async def test_get_tool_classes(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/toolClasses",
            json=[
                {"id": "1", "name": "Workflow"},
                {"id": "2", "name": "Tool"},
            ],
        )
        classes = await trs_client.get_tool_classes()
        assert len(classes) == 2
        assert classes[0].name == "Workflow"

    async def test_search_tools(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            json=[
                {"id": "tool-1", "name": "BWA"},
                {"id": "tool-2", "name": "GATK"},
            ],
        )
        tools = await trs_client.search_tools(name="bwa")
        assert len(tools) == 2
        request = httpx_mock.get_requests()[0]
        assert "name=bwa" in str(request.url)

    async def test_search_tools_with_filters(
        self, trs_client: TRSClient, httpx_mock: HTTPXMock
    ) -> None:
        httpx_mock.add_response(json=[])
        await trs_client.search_tools(
            organization="broad",
            descriptor_type=DescriptorType.CWL,
            limit=10,
            offset=0,
        )
        request = httpx_mock.get_requests()[0]
        url = str(request.url)
        assert "organization=broad" in url
        assert "descriptorType=CWL" in url
        assert "limit=10" in url

    async def test_get_tool(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/tools/tool-1",
            json={"id": "tool-1", "name": "BWA-MEM"},
        )
        tool = await trs_client.get_tool("tool-1")
        assert tool.id == "tool-1"
        assert tool.name == "BWA-MEM"

    async def test_get_tool_versions(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/tools/tool-1/versions",
            json=[
                {"id": "v1.0", "is_production": True},
                {"id": "v2.0", "is_production": False},
            ],
        )
        versions = await trs_client.get_tool_versions("tool-1")
        assert len(versions) == 2
        assert versions[0].is_production is True

    async def test_get_tool_version(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/tools/tool-1/versions/v1.0",
            json={"id": "v1.0", "name": "Release 1.0"},
        )
        version = await trs_client.get_tool_version("tool-1", "v1.0")
        assert version.id == "v1.0"

    async def test_get_descriptor(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/tools/tool-1/versions/v1.0/CWL/descriptor",
            json={"content": "class: Workflow\nsteps: []"},
        )
        desc = await trs_client.get_descriptor("tool-1", "v1.0", DescriptorType.CWL)
        assert desc.content.startswith("class:")

    async def test_get_descriptor_files(self, trs_client: TRSClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/trs/v2/tools/tool-1/versions/v1.0/CWL/files",
            json=[
                {"content": "main.cwl", "url": "https://example.com/main.cwl"},
                {"content": "tools.cwl", "url": "https://example.com/tools.cwl"},
            ],
        )
        files = await trs_client.get_descriptor_files("tool-1", "v1.0", DescriptorType.CWL)
        assert len(files) == 2
