from types import SimpleNamespace
from unittest.mock import Mock

import pytest

from dsg_core import exceptions
from dsg_core.api.v1.routes import reports


def test_download_report_logs_failed_celery_task(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    failed_result = SimpleNamespace(
        ready=lambda: True,
        successful=lambda: False,
        state="FAILURE",
        result=RuntimeError("boom"),
        traceback="traceback text",
    )

    monkeypatch.setattr(
        reports.ReportService,
        "get_report_entry",
        lambda job_id, *, session: None,
    )
    monkeypatch.setattr(
        reports,
        "celery",
        SimpleNamespace(AsyncResult=lambda job_id: failed_result),
    )
    error_log = Mock()
    monkeypatch.setattr(reports.logger, "error", error_log)

    with pytest.raises(exceptions.Error, match="Error generating report"):
        reports.download_report(
            "job-123",
            token=SimpleNamespace(token="service-token"),
            session=object(),
        )

    error_log.assert_called_once()
    message, job_id, state, result, traceback = error_log.call_args.args
    assert "Report generation failed for job_id=%s" in message
    assert job_id == "job-123"
    assert state == "FAILURE"
    assert repr(result) == "RuntimeError('boom')"
    assert traceback == "traceback text"


def test_start_report_generation_accepts_null_filters(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    params = reports.QueryParamsV2.model_validate(
        {
            "itemTypeId": "00000000-0000-0000-0000-000000000001",
            "filters": None,
            "versions": ["3.3"],
        }
    )

    monkeypatch.setattr(
        reports.ReportService,
        "build_query_payload",
        lambda params, **kwargs: {"query": "payload"},
    )
    monkeypatch.setattr(
        reports.ReportService,
        "build_report_request_id",
        lambda payload: "request-123",
    )
    monkeypatch.setattr(
        reports.ReportService,
        "get_cached_report",
        lambda request_id, *, session: None,
    )
    monkeypatch.setattr(reports, "is_task_already_scheduled", lambda task_id: False)
    monkeypatch.setattr(
        reports.query_to_report,
        "apply_async",
        lambda **kwargs: SimpleNamespace(id="job-123"),
    )
    info_log = Mock()
    monkeypatch.setattr(reports.logger, "info", info_log)

    response = reports.start_report_generation(
        params=params,
        include_alias=False,
        output_format="csv",
        token=SimpleNamespace(
            user=SimpleNamespace(uid="00000000-0000-0000-0000-000000000002"),
            token="service-token",
        ),
        session=object(),
    )

    assert response.job_id == "job-123"
    first_message = info_log.call_args_list[0].args
    assert "Received report generation request" in first_message[0]
    assert first_message[-1] == 0
