use std::io::{Read, Write};
use std::net::TcpStream;
use std::time::{Duration, Instant};
use supermachine::{Image, Vm, VmConfig};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bundle_dir = std::env::args()
.nth(1)
.ok_or("usage: tcp_forward <BUNDLE_DIR> [HOST_PORT]")?;
let host_port: u16 = std::env::args()
.nth(2)
.map(|s| s.parse())
.transpose()?
.unwrap_or(0);
let t0 = Instant::now();
let image = Image::from_snapshot(&bundle_dir)?;
let vm = Vm::start(&image, &VmConfig::new())?;
eprintln!("vm started in {:?}", t0.elapsed());
let fwd = vm.expose_tcp(host_port, 80)?;
eprintln!("listening on {} → guest", fwd.local_addr());
let mut tcp = TcpStream::connect(fwd.local_addr())?;
tcp.set_read_timeout(Some(Duration::from_secs(2)))?;
tcp.write_all(b"GET / HTTP/1.1\r\nHost: workload\r\nConnection: close\r\n\r\n")?;
let mut response = Vec::new();
tcp.read_to_end(&mut response)?;
let preview = String::from_utf8_lossy(&response);
for line in preview.lines().take(4) {
eprintln!(" {line}");
}
drop(fwd); vm.stop()?;
eprintln!("done in {:?}", t0.elapsed());
Ok(())
}