use crate::protocol::{Request, Response};
use crate::Command;
use anyhow::{Context, Result};
use std::path::Path;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::UnixStream;
pub async fn send_command(socket_path: &Path, command: Command) -> Result<()> {
let request = match command {
Command::AddPeer { ticket } => Request::AddPeer { ticket },
Command::RemovePeer { ticket } => Request::RemovePeer { ticket },
Command::Expose { port, to } => Request::Expose { port, to },
Command::Unexpose { port, to } => Request::Unexpose { port, to },
Command::List => Request::List,
Command::Ticket => Request::Ticket,
Command::GrantToken { label } => Request::GrantToken { label },
Command::Pin { key, label } => Request::Pin { key, label },
Command::Project { peer, ip, name } => Request::Project {
peer,
ip: ip.map(|ip| ip.to_string()),
name,
},
Command::Unproject { peer } => Request::Unproject { peer },
Command::Surfaces => Request::Surfaces,
Command::Daemon { .. } => unreachable!("daemon handled separately"),
};
let stream = UnixStream::connect(socket_path)
.await
.context("failed to connect to daemon - is it running?")?;
let (reader, mut writer) = stream.into_split();
let mut reader = BufReader::new(reader);
let request_json = serde_json::to_string(&request)?;
writer.write_all(request_json.as_bytes()).await?;
writer.write_all(b"\n").await?;
let mut line = String::new();
reader.read_line(&mut line).await?;
let response: Response = serde_json::from_str(&line)?;
match response {
Response::Ok => println!("OK"),
Response::Ticket(ticket) => println!("{}", ticket),
Response::Token(token) => println!("{}", token),
Response::List(info) => {
println!("{}", serde_json::to_string_pretty(&info)?);
}
Response::Surfaces(surfaces) => {
println!("{}", serde_json::to_string_pretty(&surfaces)?);
}
Response::Error(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
Ok(())
}