use crate::compose::{build_message, ComposeArgs};
use crate::profile::load_profile;
use crate::{CliError, CliResult};
use clap::Args;
use std::io::{self, Write};
use std::process::Command;
#[derive(Debug, Args)]
pub struct SendHerdrArgs {
#[arg(long, help = "Target herdr pane id.")]
pub pane: String,
#[arg(long, help = "Print composed message without sending.")]
pub dry_run: bool,
#[arg(long, default_value = "herdr", help = "herdr executable path.")]
pub herdr_bin: String,
#[command(flatten)]
pub compose: ComposeArgs,
}
pub fn run(args: SendHerdrArgs) -> CliResult<()> {
let profile = load_profile(args.compose.profile.as_deref())?;
let message = build_message(&args.compose, &profile)?;
if args.dry_run {
eprintln!("DRY RUN: message was not sent; do not record delivery_status=sent.");
println!("{message}");
return Ok(());
}
let output = Command::new(&args.herdr_bin)
.args(["pane", "run", &args.pane, &message])
.output();
let output = match output {
Ok(output) => output,
Err(error) if error.kind() == io::ErrorKind::NotFound => {
return Err(CliError::with_code(
127,
format!("herdr CLI not found at {}", args.herdr_bin),
))
}
Err(error) => return Err(CliError::failure(format!("failed to run herdr: {error}"))),
};
io::stdout()
.write_all(&output.stdout)
.map_err(|error| CliError::failure(format!("failed to write stdout: {error}")))?;
io::stderr()
.write_all(&output.stderr)
.map_err(|error| CliError::failure(format!("failed to write stderr: {error}")))?;
if output.status.success() {
Ok(())
} else {
Err(CliError::with_code(
output.status.code().unwrap_or(1),
"herdr pane run failed",
))
}
}