use std::time::Duration;
use std::net::SocketAddr;
use tracing::{info, Level};
use tracing_subscriber;

#[momo::main]
async fn main() {
    // Initialize tracing
    tracing_subscriber::fmt()
        .with_max_level(Level::DEBUG)
        .init();

    info!("--- Momo Runtime Starting with Tracing & Sync ---");
    let addr: SocketAddr = "127.0.0.1:9091".parse().unwrap();
    let (tx, rx) = momo::sync::oneshot::channel();
    
    momo::spawn(async move {
        info!("Server: Binding to {}...", addr);
        let listener = momo::net::TcpListener::bind(addr).unwrap();
        
        // Signal client that we are ready
        tx.send(()).unwrap();
        
        let (stream, _) = listener.accept().await.unwrap();
        info!("Server: Accepted connection!");
        
        let mut buf = [0u8; 5];
        stream.read(&mut buf).await.unwrap();
        info!("Server: Received: {}", String::from_utf8_lossy(&buf));
        
        stream.write(b"world").await.unwrap();
        info!("Server: Sent response");
        
        momo::time::sleep(Duration::from_millis(100)).await;
        info!("--- Shutting down Momo gracefully ---");
        momo::stop();
    });

    momo::spawn(async move {
        // Wait for server to be ready
        rx.await.unwrap();
        
        info!("Client: Connecting to server...");
        let stream = momo::net::TcpStream::connect(addr).await.unwrap();
        
        info!("Client: Sending 'hello'...");
        stream.write(b"hello").await.unwrap();
        
        let mut buf = [0u8; 5];
        stream.read(&mut buf).await.unwrap();
        info!("Client: Received: {}", String::from_utf8_lossy(&buf));
    });
}
