"""
Integration test: start server with job_push, submit queued job, receive event via /ws.

Requires server running with queue_manager and job_push enabled (e.g. full_application
with configs/http_basic.json). Run server first:
  python mcp_proxy_adapter/examples/full_application/main.py --config .../http_basic.json --port 8080

Then: pytest tests/test_job_push_ws_integration.py -v -m integration
Or run as script: python tests/test_job_push_ws_integration.py

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

import asyncio
import os
import sys
from pathlib import Path

import pytest

# Add project root
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from mcp_proxy_adapter.client.jsonrpc_client import JsonRpcClient
from mcp_proxy_adapter.client.jsonrpc_client.ws_job_status import (
    wait_for_job_via_websocket,
)


def _server_available(host: str = "127.0.0.1", port: int = 8080) -> bool:
    """Check if server is reachable (health endpoint)."""
    try:
        import httpx

        r = httpx.get(f"http://{host}:{port}/health", timeout=2.0)
        return r.status_code == 200
    except Exception:
        return False


@pytest.fixture
def client():
    """HTTP client for local server (no token)."""
    return JsonRpcClient(
        protocol="http",
        host="127.0.0.1",
        port=8080,
    )


@pytest.mark.asyncio
@pytest.mark.integration
@pytest.mark.skipif(
    not _server_available(),
    reason="Server not running on 127.0.0.1:8080 (start full_application with http_basic.json)",
)
async def test_submit_job_and_receive_push_via_ws(client: JsonRpcClient) -> None:
    """Submit a queued command, get job_id, subscribe via /ws, receive job_completed."""
    # Use long_running_task (queued) with short duration so it completes quickly
    result = await client.jsonrpc_call(
        "long_running_task",
        {"seconds": 1},
    )
    data = result.get("result", result) if isinstance(result, dict) else {}
    job_id = data.get("job_id") or data.get("data", {}).get("job_id")
    assert job_id, f"Expected job_id in response: {data}"

    # Wait for completion via WebSocket (built-in /ws + job push)
    event = await asyncio.wait_for(
        wait_for_job_via_websocket(client, job_id, timeout=30.0),
        timeout=35.0,
    )
    assert event.get("event") in ("job_completed", "job_failed", "job_stopped")
    assert event.get("job_id") == job_id
    if event.get("event") == "job_completed":
        assert "result" in event or "result" in event.get("data", {})


if __name__ == "__main__":
    # Run as script: start server if SERVER_URL not set, then run test
    port = int(os.environ.get("PORT", "8080"))
    host = os.environ.get("HOST", "127.0.0.1")
    cl = JsonRpcClient(protocol="http", host=host, port=port)

    async def main():
        print("Submitting long_running_task(seconds=2)...")
        result = await cl.jsonrpc_call("long_running_task", {"seconds": 2})
        data = result.get("result", result) if isinstance(result, dict) else {}
        job_id = data.get("job_id") or data.get("data", {}).get("job_id")
        if not job_id:
            print("No job_id:", data)
            return
        print("job_id:", job_id)
        print("Waiting for job completion via WebSocket...")
        event = await wait_for_job_via_websocket(cl, job_id, timeout=30.0)
        print("Event:", event)

    asyncio.run(main())
