from uuid import UUID
from unittest.mock import AsyncMock

import pytest

from dsg_core_client import DSGCoreClient
from dsg_core_client.schemas import QueryRequest


@pytest.mark.asyncio
async def test_start_report_generation_calls_reports_items_endpoint() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        client.post = AsyncMock(return_value={"jobId": "job-123"})  # type: ignore[method-assign]
        request = QueryRequest(
            item_type_id=UUID("00000000-0000-0000-0000-000000000001")
        )

        response = await client.reports.start_report_generation(
            request, include_alias=True
        )

        assert response.job_id == "job-123"
        client.post.assert_awaited_once_with(
            client.path("/reports/items"),
            json=client.dump(request),
            params={"includeAlias": True},
        )
    finally:
        await client.close()


@pytest.mark.asyncio
async def test_download_report_uses_get_bytes() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        client.get_bytes = AsyncMock(return_value=b"file-bytes")  # type: ignore[method-assign]
        client.bgtasks.wait_for_task = AsyncMock()  # type: ignore[method-assign]

        content = await client.reports.download_report("job-456")

        assert content == b"file-bytes"
        client.bgtasks.wait_for_task.assert_awaited_once_with(
            job_id="job-456",
            timeout_seconds=300.0,
            poll_interval_seconds=1.0,
        )
        client.get_bytes.assert_awaited_once_with(client.path("/reports/job-456"))
    finally:
        await client.close()


@pytest.mark.asyncio
async def test_download_report_can_skip_wait() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        client.get_bytes = AsyncMock(return_value=b"file-bytes")  # type: ignore[method-assign]
        client.bgtasks.wait_for_task = AsyncMock()  # type: ignore[method-assign]

        content = await client.reports.download_report("job-456", wait_for_ready=False)

        assert content == b"file-bytes"
        client.bgtasks.wait_for_task.assert_not_called()
        client.get_bytes.assert_awaited_once_with(client.path("/reports/job-456"))
    finally:
        await client.close()


@pytest.mark.asyncio
async def test_download_report_rejects_empty_job_id() -> None:
    client = DSGCoreClient(base_url="https://example.org", token="token")
    try:
        with pytest.raises(ValueError, match="job_id must be a non-empty string"):
            await client.reports.download_report("")
    finally:
        await client.close()
