use std::path::PathBuf;
use clap::Args;
use crate::error::{CliError, CliResult};
use crate::output::{print_success, OutputFormat};
#[derive(Debug, Clone, Args)]
pub struct StartArgs {
#[arg(long, default_value_t = 50050)]
pub grpc_port: u16,
#[arg(long, default_value_t = 8080)]
pub http_port: u16,
#[arg(long, default_value_t = 9090)]
pub metrics_port: u16,
#[arg(long)]
pub foreground: bool,
#[arg(long)]
pub config: Option<PathBuf>,
}
pub async fn execute(args: StartArgs, fmt: &OutputFormat, quiet: bool) -> CliResult<()> {
let server_bin = std::env::current_exe()
.ok()
.and_then(|p| p.parent().map(|d| d.join("clawdb-server")))
.unwrap_or_else(|| PathBuf::from("clawdb-server"));
let mut cmd = std::process::Command::new(&server_bin);
cmd.arg("--grpc-port")
.arg(args.grpc_port.to_string())
.arg("--http-port")
.arg(args.http_port.to_string())
.arg("--metrics-port")
.arg(args.metrics_port.to_string());
if let Some(cfg_path) = &args.config {
cmd.arg("--config").arg(cfg_path);
}
if args.foreground {
let status = cmd.status()?;
if !status.success() {
let code = status.code().unwrap_or(1);
return Err(CliError::Other(format!(
"clawdb-server exited with code {code}"
)));
}
} else {
let child = cmd
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()?;
let pid = child.id();
let pid_dir = crate::config::CliConfig::config_dir();
std::fs::create_dir_all(&pid_dir)?;
std::fs::write(pid_dir.join("server.pid"), pid.to_string())?;
print_success(&format!("ClawDB server started (pid: {pid})"), fmt, quiet);
}
Ok(())
}