import grantflow.api.routes.jobs as jobs_routes
from grantflow.api import runtime_state
from grantflow.core.config import config

from grantflow.tests.integration_helpers import wait_for_terminal_status
from grantflow.tests.queue_dispatch_helpers import client


def test_resume_uses_redis_queue_dispatch_by_job_id(monkeypatch):
    captured: dict = {}

    def _submit_stub(fn, *args, **kwargs):
        captured["fn"] = fn
        captured["args"] = args
        captured["kwargs"] = kwargs
        return True

    checkpoint_id = runtime_state.hitl_manager.create_checkpoint(
        stage="toc",
        state={"donor_id": "usaid", "input_context": {"project": "Resume redis", "country": "Kenya"}},
        donor_id="usaid",
    )
    runtime_state.hitl_manager.approve(checkpoint_id, "approved")

    job_id = "resume-redis-dispatch-job-1"
    runtime_state.JOB_STORE.set(
        job_id,
        {
            "status": "pending_hitl",
            "state": {
                "donor_id": "usaid",
                "input_context": {"project": "Resume redis", "country": "Kenya"},
                "hitl_pending": True,
            },
            "hitl_enabled": True,
            "checkpoint_id": checkpoint_id,
            "checkpoint_stage": "toc",
            "resume_from": "mel",
        },
    )

    monkeypatch.setattr(config.job_runner, "mode", "redis_queue")
    monkeypatch.setattr(runtime_state.JOB_RUNNER, "submit", _submit_stub)

    response = client.post(f"/resume/{job_id}", json={})
    assert response.status_code == 200
    assert response.json()["resuming_from"] == "mel"

    assert captured["fn"] == jobs_routes._run_hitl_pipeline_by_job_id
    assert captured["args"] == (job_id, "mel")


def test_resume_returns_503_and_keeps_pending_hitl_when_queue_full(monkeypatch):
    response = client.post(
        "/generate",
        json={
            "donor_id": "usaid",
            "input_context": {"project": "Resume queue full", "country": "Kenya"},
            "llm_mode": False,
            "hitl_enabled": True,
        },
    )
    assert response.status_code == 200
    job_id = response.json()["job_id"]
    status = wait_for_terminal_status(client, job_id)
    assert status["status"] == "pending_hitl"
    checkpoint_id = status["checkpoint_id"]

    approve = client.post(
        "/hitl/approve",
        json={"checkpoint_id": checkpoint_id, "approved": True, "feedback": "approved"},
    )
    assert approve.status_code == 200

    monkeypatch.setattr(config.job_runner, "mode", "inmemory_queue")
    monkeypatch.setattr(runtime_state.JOB_RUNNER, "submit", lambda *args, **kwargs: False)

    resume = client.post(f"/resume/{job_id}", json={})
    assert resume.status_code == 503
    assert resume.json()["detail"]["code"] == "job_queue_full"

    status_after = client.get(f"/status/{job_id}")
    assert status_after.status_code == 200
    body = status_after.json()
    assert body["status"] == "pending_hitl"
    assert body["checkpoint_id"] == checkpoint_id
    assert body["checkpoint_stage"] == "toc"
