"""Testy monoliticke FastAPI aplikace (Faze 4).

Testy se deli na:
- Sub-app testy: /safe-oi/*, / (webapp) - nevyzaduji bezici sluzby
- Agregovany /health: vyzaduje bezici sluzby na 4100/7782/8180
"""
from __future__ import annotations

import socket

import pytest
from fastapi.testclient import TestClient

from cyberbrain26.app import app


@pytest.fixture
def client() -> TestClient:
    return TestClient(app)


def _port_open(port: int, timeout: float = 0.3) -> bool:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout)
    try:
        return s.connect_ex(("127.0.0.1", port)) == 0
    finally:
        s.close()


def test_webapp_root(client: TestClient) -> None:
    """Webapp root vrací status (nepotřebuje externí služby)."""
    r = client.get("/")
    assert r.status_code == 200
    body = r.json()
    assert body.get("status") == "ok"


def test_safe_oi_health_via_monolith(client: TestClient) -> None:
    """safe_oi /health pod /safe-oi/ prefixem."""
    r = client.get("/safe-oi/health")
    assert r.status_code == 200
    body = r.json()
    assert body.get("status") == "ok"
    assert body.get("service") == "safe_oi_api"


def test_safe_oi_sessions_via_monolith(client: TestClient) -> None:
    """safe_oi /sessions pod /safe-oi/ prefixem."""
    r = client.get("/safe-oi/sessions")
    assert r.status_code == 200
    body = r.json()
    assert "sessions" in body


def test_webapp_v1_worktree_via_monolith(client: TestClient) -> None:
    """webapp /v1/worktree/tasks pod monolit root."""
    r = client.get("/v1/worktree/tasks")
    assert r.status_code == 200
    body = r.json()
    assert "tasks" in body


def test_no_safe_oi_at_root(client: TestClient) -> None:
    """safe_oi endpointy NEJSOU na rootu (jsou jen pod /safe-oi/)."""
    r = client.get("/sessions")
    # root /sessions neexistuje ve webapp, mel by vratit 404
    assert r.status_code == 404


@pytest.mark.skipif(
    not all(_port_open(p) for p in (4100, 7782, 8180)),
    reason="Agregovany /health vyzaduje bezici sluzby 4100/7782/8180",
)
def test_aggregate_health(client: TestClient) -> None:
    """Agregovany /health vraci stav vsech tri sluzeb."""
    r = client.get("/health")
    assert r.status_code == 200
    body = r.json()
    assert body.get("status") == "ok"
    assert body.get("version") == "4.0.0"
    services = body.get("services", {})
    assert "litellm" in services
    assert "safe_oi" in services
    assert "webapp" in services
    for name, info in services.items():
        assert info.get("status") == "ok", f"{name} neni ok: {info}"
