//! Integration test for `rutster::serve::serve_with_nodelay` (deploy
//! slice A §5.1): the production serve helper round-trips a request over
//! a real socket and quiesces when the shutdown future resolves.
//!
//! The NODELAY *behavior* (no Nagle stall on 20 ms-cadence WS frames) is
//! asserted in the CI-regressed sim-bench
//! (`crates/rutster-sim/src/nodelay.rs`, Task 3) — this test pins the
//! helper's serve/shutdown contract only.

use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[tokio::test]
async fn serves_healthz_and_stops_on_shutdown_signal() {
    let app = rutster::routes::router(rutster::session_map::AppState::default());
    let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
    let addr = listener.local_addr().unwrap();
    let (stop_tx, stop_rx) = tokio::sync::oneshot::channel::<()>();
    let server = tokio::spawn(rutster::serve::serve_with_nodelay(listener, app, async {
        let _ = stop_rx.await;
    }));

    // Raw HTTP/1.1 over a plain TcpStream — no client dep needed for a
    // liveness round trip. `Connection: close` so read_to_end terminates.
    let mut stream = tokio::net::TcpStream::connect(addr).await.unwrap();
    stream
        .write_all(b"GET /healthz HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n")
        .await
        .unwrap();
    let mut buf = Vec::new();
    stream.read_to_end(&mut buf).await.unwrap();
    let response = String::from_utf8_lossy(&buf);
    assert!(response.starts_with("HTTP/1.1 200"), "got: {response}");

    stop_tx.send(()).unwrap();
    tokio::time::timeout(std::time::Duration::from_secs(5), server)
        .await
        .expect("serve future resolves after the shutdown signal")
        .expect("serve task did not panic")
        .expect("serve returned Ok");
}
