"""Tests for TES client."""

from __future__ import annotations

import pytest
from pytest_httpx import HTTPXMock

from ai4gh.specs.tes.client import TESClient
from ai4gh.specs.tes.models import TESState, TESView


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


class TestTESClient:
    def test_spec_attrs(self) -> None:
        client = TESClient(base_url="https://example.com")
        assert client.spec_name == "tes"
        assert client.spec_version == "1.1.0"
        assert client.base_path == "/ga4gh/tes/v1"

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

    async def test_create_task(self, tes_client: TESClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/tes/v1/tasks",
            method="POST",
            json={"id": "task-new"},
        )
        task_def = {
            "name": "alignment",
            "executors": [{"image": "bwa:latest", "command": ["bwa", "mem"]}],
        }
        result = await tes_client.create_task(task_def)
        assert result.id == "task-new"

    async def test_get_task(self, tes_client: TESClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/tes/v1/tasks/task-1?view=MINIMAL",
            json={"id": "task-1", "state": "RUNNING"},
        )
        task = await tes_client.get_task("task-1")
        assert task.id == "task-1"
        assert task.state is TESState.RUNNING

    async def test_get_task_full_view(self, tes_client: TESClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            json={
                "id": "task-1",
                "state": "COMPLETE",
                "name": "alignment",
                "executors": [{"image": "bwa:latest", "command": ["bwa", "mem"]}],
            }
        )
        task = await tes_client.get_task("task-1", view=TESView.FULL)
        assert task.id == "task-1"
        request = httpx_mock.get_requests()[0]
        assert "view=FULL" in str(request.url)

    async def test_list_tasks(self, tes_client: TESClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/tes/v1/tasks?view=MINIMAL",
            json={
                "tasks": [
                    {"id": "t1", "state": "COMPLETE"},
                    {"id": "t2", "state": "RUNNING"},
                ],
                "next_page_token": "page2",
            },
        )
        resp = await tes_client.list_tasks()
        assert len(resp.tasks) == 2
        assert resp.next_page_token == "page2"

    async def test_list_tasks_with_filters(
        self, tes_client: TESClient, httpx_mock: HTTPXMock
    ) -> None:
        httpx_mock.add_response(json={"tasks": []})
        await tes_client.list_tasks(
            page_size=10,
            name_prefix="align",
            state="RUNNING",
            tag_key="project",
            tag_value="genomics",
        )
        request = httpx_mock.get_requests()[0]
        url = str(request.url)
        assert "page_size=10" in url
        assert "name_prefix=align" in url
        assert "state=RUNNING" in url
        assert "tag_key=project" in url

    async def test_cancel_task(self, tes_client: TESClient, httpx_mock: HTTPXMock) -> None:
        httpx_mock.add_response(
            url="https://example.com/ga4gh/tes/v1/tasks/task-1:cancel",
            method="POST",
            json={},
        )
        result = await tes_client.cancel_task("task-1")
        assert result == {}
