#![cfg(unix)]

use super::*;
use tokio::io::{AsyncWriteExt, duplex};
use tokio::time::{Duration, Instant, timeout};

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn adversarial_delayed_interface_lookup_does_not_consume_outcome_floor_budget() {
    let mut config = ProxyConfig::default();
    config.general.beobachten = false;
    config.censorship.mask = true;
    config.censorship.mask_unix_sock = None;
    config.censorship.mask_host = Some("127.0.0.1".to_string());
    config.censorship.mask_port = 443;
    config.censorship.mask_timing_normalization_enabled = true;
    config.censorship.mask_timing_normalization_floor_ms = 120;
    config.censorship.mask_timing_normalization_ceiling_ms = 120;

    let peer: SocketAddr = "203.0.113.151:55151".parse().expect("valid peer");
    let local_addr: SocketAddr = "0.0.0.0:443".parse().expect("valid local addr");
    let beobachten = BeobachtenStore::new();

    let refresh_lock = LOCAL_INTERFACE_REFRESH_LOCK.get_or_init(|| AsyncMutex::new(()));
    let held_refresh_guard = refresh_lock.lock().await;
    reset_local_interface_enumerations_for_tests();

    let (mut client, server) = duplex(1024);
    let started = Instant::now();
    let task = tokio::spawn(async move {
        handle_bad_client(
            server,
            tokio::io::sink(),
            b"GET / HTTP/1.1\r\n\r\n",
            peer,
            local_addr,
            &config,
            &beobachten,
        )
        .await;
    });

    tokio::time::sleep(Duration::from_millis(80)).await;
    drop(held_refresh_guard);
    client
        .shutdown()
        .await
        .expect("client shutdown must succeed");

    timeout(Duration::from_secs(2), task)
        .await
        .expect("task must finish in bounded time")
        .expect("task must not panic");
    let elapsed = started.elapsed();

    assert!(
        elapsed >= Duration::from_millis(180) && elapsed < Duration::from_millis(350),
        "timing normalization floor must start after pre-outcome self-target checks"
    );
}
