use std::time::Duration;
use std::net::SocketAddr;
use std::rc::Rc;
use std::cell::Cell;

#[momo::main]
async fn main() {
    let addr: SocketAddr = "127.0.0.1:9999".parse().unwrap();
    let listener = momo::net::TcpListener::bind(addr).unwrap();

    let finished = Rc::new(Cell::new(false));
    let finished_clone = finished.clone();

    momo::spawn(async move {
        let (stream, _) = listener.accept().await.unwrap();
        let mut buf = [0u8; 5];
        stream.read(&mut buf).await.unwrap();
        assert_eq!(&buf, b"hello");
        finished_clone.set(true);
    });

    momo::spawn(async move {
        momo::time::sleep(Duration::from_millis(10)).await;
        let stream = momo::net::TcpStream::connect(addr).await.unwrap();
        stream.write(b"hello").await.unwrap();
    });

    // Wait until finished
    while !finished.get() {
        momo::time::sleep(Duration::from_millis(1)).await;
    }

    // In a real main, we could exit here. 
    // Since our macro has a loop {}, we can't easily exit main in this draft,
    // but we can use std::process::exit(0) for a test.
    std::process::exit(0);
}
