"""Tests for multiprocessing worker."""

import pytest
from sqlmodel import select

from ..factories import create_job
from ..models import TASK_COMPLETED, TASK_PENDING_CLEANUP, Task
from ..orch_context import get_sql_session
from .mp_worker import mp_worker_main_loop

pytestmark = pytest.mark.usefixtures("fast_poll")


async def test_mp_worker_executes_task(orch_ctx_no_ch):
    """Test that mp worker executes a task in a child process."""
    job = await create_job(
        "test_mp_job",
        "aaiclick.orchestration.fixtures.sample_tasks.simple_task",
    )

    tasks_executed = await mp_worker_main_loop(
        max_tasks=1,
        install_signal_handlers=False,
        max_empty_polls=1,
    )

    assert tasks_executed == 1

    async with get_sql_session() as session:
        result = await session.execute(select(Task).where(Task.job_id == job.id))
        task = result.scalar_one()
        assert task.status == TASK_COMPLETED


async def test_mp_worker_handles_failure(orch_ctx_no_ch):
    """Test that mp worker handles task failures from child process.

    Asserts the recorded error matches the message raised by ``failing_task``
    so a child crash on chdb setup, an exit-code-only failure, or a timeout
    can't masquerade as a passing test.
    """
    job = await create_job(
        "test_mp_failing_job",
        "aaiclick.orchestration.fixtures.sample_tasks.failing_task",
    )

    tasks_executed = await mp_worker_main_loop(
        max_tasks=1,
        install_signal_handlers=False,
        max_empty_polls=1,
    )

    assert tasks_executed == 0

    async with get_sql_session() as session:
        result = await session.execute(select(Task).where(Task.job_id == job.id))
        task = result.scalar_one()
        assert task.status == TASK_PENDING_CLEANUP
        assert task.error == "This task failed intentionally"


async def test_mp_worker_no_tasks(orch_ctx_no_ch):
    """Test that mp worker exits after max_empty_polls with no tasks."""
    tasks_executed = await mp_worker_main_loop(
        install_signal_handlers=False,
        max_empty_polls=1,
    )

    assert tasks_executed == 0
