use std::io::{BufRead, Write};
use tokio::sync::mpsc;
use tokio::task::JoinSet;
use crate::mcp::{self, Host};
pub async fn serve(host: Host) {
let (lines, mut incoming) = mpsc::unbounded_channel::<String>();
let reader = tokio::task::spawn_blocking(move || {
for line in std::io::stdin().lock().lines() {
let Ok(line) = line else { return };
if lines.send(line).is_err() {
return;
}
}
});
let mut answering = JoinSet::new();
let mut open = true;
while open || !answering.is_empty() {
tokio::select! {
line = incoming.recv(), if open => match line {
Some(line) => {
let host = host.clone();
answering.spawn(async move { mcp::handle_line(&line, &host).await });
}
None => open = false,
},
Some(done) = answering.join_next(), if !answering.is_empty() => {
write(done.ok().flatten());
}
}
}
let _ = reader.await;
}
fn write(reply: Option<String>) {
let Some(reply) = reply else { return };
let mut out = std::io::stdout().lock();
let _ = writeln!(out, "{reply}");
let _ = out.flush();
}