use super::prelude::*;
use super::shared_harness::*;

#[tokio::test]
async fn rpc_response_arriving_during_child_health_grace_is_delivered() {
    let h = RpcSleepHarness::spawn_sleep("10", SleepStdoutDrainMode::SmallBuf).await;
    let child_pid = h.child_pid();
    let (tx, rx) = tokio::sync::oneshot::channel::<Result<Value, String>>();
    let (pending_tx, _pending_rx) = tokio::sync::oneshot::channel::<Result<Value, String>>();
    let request_id = 99_u64;
    h.pending.lock().await.insert(request_id, pending_tx);
    let timeout = Duration::from_millis(100);
    let grace = crate::child_health::silence_grace_for_rpc_timeout(timeout);
    let response_time = timeout + grace / 2;
    tokio::spawn({
        let tx = tx;
        async move {
            tokio::time::sleep(response_time).await;
            let _ = tx.send(Ok(json!({"ok": true})));
        }
    });
    let start = tokio::time::Instant::now();
    let res = tokio::time::timeout(
        std::time::Duration::from_secs(1),
        harness_rpc_wait(HarnessRpcWaitParams {
            h: &h,
            request_id,
            timeout,
            rx,
            child_pid,
        }),
    )
    .await
    .expect("request wait timed out")
    .expect("response should arrive before health grace expires");
    assert!(start.elapsed() >= response_time);
    assert_eq!(res["ok"], true);
    assert!(
        !h.pending.lock().await.contains_key(&request_id),
        "request should be removed from pending after completion"
    );
    h.shutdown().await;
}

#[cfg(test)]
mod kiss_cov_auto {
    #[test]
    fn kiss_cov_rpc_response_arriving_during_child_health_grace_is_delivered() { let _ = stringify!(rpc_response_arriving_during_child_health_grace_is_delivered); }

}
