"""Integration tests for Astromesh Node Phase 2 — services and peers."""

import pytest
from asgi_lifespan import LifespanManager
from httpx import ASGITransport, AsyncClient

from astromesh.api.main import app
from astromesh.api.routes import system
from astromesh.runtime.engine import AgentRuntime
from astromesh.runtime.peers import PeerClient
from astromesh.runtime.services import ServiceManager


@pytest.fixture(autouse=True)
def _skip_runtime_lifespan(monkeypatch):
    monkeypatch.setenv("ASTROMESH_SKIP_RUNTIME", "1")

AGENT_YAML = """
apiVersion: astromesh/v1
kind: Agent
metadata:
  name: test-agent
  version: "1.0.0"
  namespace: testing
spec:
  identity:
    display_name: Test Agent
    description: A test agent
  model:
    primary:
      provider: ollama
      model: test-model
      endpoint: http://localhost:11434
  prompts:
    system: "You are a test agent."
  orchestration:
    pattern: react
    max_iterations: 3
"""


@pytest.fixture
async def worker_node(tmp_path):
    agents_dir = tmp_path / "agents"
    agents_dir.mkdir()
    (agents_dir / "test.agent.yaml").write_text(AGENT_YAML)

    sm = ServiceManager({"agents": True, "inference": False, "channels": False})
    pc = PeerClient(
        [
            {"name": "inference-1", "url": "http://inference:8000", "services": ["inference"]},
        ]
    )

    runtime = AgentRuntime(config_dir=str(tmp_path), service_manager=sm, peer_client=pc)
    await runtime.bootstrap()
    system.set_runtime(runtime)

    async with LifespanManager(app):
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            yield client, runtime

    system.set_runtime(None)
    await pc.close()


async def test_worker_node_status(worker_node):
    client, runtime = worker_node
    resp = await client.get("/v1/system/status")
    assert resp.status_code == 200
    data = resp.json()

    assert data["agents_loaded"] == 1
    assert data["services"]["agents"] is True
    assert data["services"]["inference"] is False
    assert data["services"]["channels"] is False
    assert len(data["peers"]) == 1
    assert data["peers"][0]["name"] == "inference-1"


async def test_worker_node_doctor(worker_node):
    client, runtime = worker_node
    resp = await client.get("/v1/system/doctor")
    assert resp.status_code == 200
    data = resp.json()

    assert data["checks"]["runtime"]["status"] == "ok"
    assert "peer:inference-1" in data["checks"]
    assert data["checks"]["peer:inference-1"]["status"] == "unreachable"


@pytest.fixture
async def gateway_node(tmp_path):
    sm = ServiceManager(
        {"agents": False, "inference": False, "tools": False, "memory": False, "rag": False}
    )
    pc = PeerClient(
        [
            {
                "name": "worker-1",
                "url": "http://worker:8000",
                "services": ["agents", "tools", "memory"],
            },
        ]
    )

    runtime = AgentRuntime(config_dir=str(tmp_path), service_manager=sm, peer_client=pc)
    await runtime.bootstrap()
    system.set_runtime(runtime)

    async with LifespanManager(app):
        async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
            yield client, runtime

    system.set_runtime(None)
    await pc.close()


async def test_gateway_node_no_agents(gateway_node):
    client, runtime = gateway_node
    resp = await client.get("/v1/system/status")
    assert resp.status_code == 200
    data = resp.json()
    assert data["agents_loaded"] == 0
    assert data["services"]["agents"] is False
