//! Regression test: 64-char node_ids (Iroh `EndpointId` hex) must work
//! through the `advertise()` / `enable_addr_auto` path that
//! peat-mesh-node and the consolidated quickstart use.
//!
//! Before the DNS-label fix in this PR, building `instance_name` as
//! `format!("peat-{node_id}")` produced a 69-octet label for a 64-char
//! hex id, violating RFC 1035 §2.3.4 (63-octet DNS label limit), and
//! `mdns_sd::ServiceDaemon` silently rejected the registration. The
//! receive side never saw a `ServiceResolved` for the offending peer.
//!
//! `#[ignore]` for the same multicast-reliability reasons as the
//! companion `mdns_advertise_with_addr` test.

use peat_mesh::discovery::{DiscoveryStrategy, MdnsDiscovery};
use std::time::{Duration, Instant};

#[tokio::test]
#[ignore = "requires working multicast; run with --ignored on bare metal"]
async fn long_node_id_round_trips_through_advertise() {
    let mut a = MdnsDiscovery::new().unwrap();
    let mut b = MdnsDiscovery::new().unwrap();
    a.start().await.unwrap();
    b.start().await.unwrap();
    // Exactly-64-char ids — the RFC 1035 §2.3.4 DNS-label boundary under test —
    // but run-unique so two P2P CI jobs sharing the multicast group don't
    // collide on the mDNS service-instance name. A run-scoped prefix is padded
    // out to exactly 64 chars, preserving the boundary the test exercises.
    let uniq = format!(
        "{}{}",
        std::process::id(),
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos()
    );
    let long_a: String = format!("a{uniq}")
        .chars()
        .chain(std::iter::repeat('a'))
        .take(64)
        .collect();
    let long_b: String = format!("b{uniq}")
        .chars()
        .chain(std::iter::repeat('b'))
        .take(64)
        .collect();
    assert_eq!(long_a.len(), 64, "id must stay at the 64-char boundary");
    assert_eq!(long_b.len(), 64, "id must stay at the 64-char boundary");
    a.advertise(&long_a, 39001, None).unwrap();
    b.advertise(&long_b, 39002, None).unwrap();

    // Measure the real round-trip so a regression surfaces as a visible delta
    // rather than only as a timeout under the generous 20s ceiling (#229 QA
    // suggestion). Discovery is normally 1-3s; warn loudly past a healthy budget.
    let start = Instant::now();
    let deadline = start + Duration::from_secs(20);
    loop {
        let ap = a.discovered_peers().await;
        let bp = b.discovered_peers().await;
        if ap.iter().any(|p| p.node_id == long_b) && bp.iter().any(|p| p.node_id == long_a) {
            let elapsed = start.elapsed();
            if elapsed > Duration::from_secs(8) {
                eprintln!(
                    "[mdns][WARN] 64-char node_id discovery took {elapsed:?} — well above the \
                     typical 1-3s round-trip; investigate runner contention or an mDNS regression"
                );
            } else {
                eprintln!("[mdns] 64-char node_id discovery in {elapsed:?}");
            }
            return;
        }
        if Instant::now() > deadline {
            panic!(
                "64-char node_id discovery timed out after {:?}: A peers {ap:?} B peers {bp:?}",
                start.elapsed()
            );
        }
        tokio::time::sleep(Duration::from_millis(200)).await;
    }
}
