use crate::ui;
use anyhow::Result;
use dialoguer::{theme::ColorfulTheme, Select};
const COMMANDS: &[(&str, &str, &[&str])] = &[
(
"dev up",
"Start development services",
&["oph", "dev", "up"],
),
(
"dev down",
"Stop development services",
&["oph", "dev", "down"],
),
(
"dev status",
"Show development status",
&["oph", "dev", "status"],
),
("dev logs", "View development logs", &["oph", "dev", "logs"]),
(
"dev restart",
"Restart development services",
&["oph", "dev", "restart"],
),
(
"dev rebuild",
"Rebuild development services",
&["oph", "dev", "rebuild"],
),
(
"dev setup",
"Setup development environment",
&["oph", "dev", "setup"],
),
(
"prod up",
"Start production services",
&["oph", "prod", "up"],
),
(
"prod down",
"Stop production services",
&["oph", "prod", "down"],
),
(
"prod status",
"Show production status",
&["oph", "prod", "status"],
),
(
"prod logs",
"View production logs",
&["oph", "prod", "logs"],
),
(
"db shell",
"Open database shell (dev)",
&["oph", "db", "shell"],
),
(
"db shell --prod",
"Open database shell (prod)",
&["oph", "db", "shell", "--prod"],
),
(
"db backup",
"Backup database (dev)",
&["oph", "db", "backup"],
),
(
"db backup --prod",
"Backup database (prod)",
&["oph", "db", "backup", "--prod"],
),
("run dev", "Start dev server", &["oph", "run", "dev"]),
("run test", "Run all tests", &["oph", "run", "test"]),
("run lint", "Run linter", &["oph", "run", "lint"]),
(
"run typecheck",
"Run type checking",
&["oph", "run", "typecheck"],
),
(
"redis cli",
"Open Redis CLI (dev)",
&["oph", "redis", "cli"],
),
(
"validate dev",
"Validate dev config",
&["oph", "validate", "dev"],
),
(
"validate prod",
"Validate prod config",
&["oph", "validate", "prod"],
),
];
pub fn run() -> Result<()> {
ui::header("OpenHealth CLI - Interactive Mode");
println!();
let items: Vec<String> = COMMANDS
.iter()
.map(|(name, desc, _)| format!("{name:<20} {desc}"))
.collect();
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Select a command")
.items(&items)
.default(0)
.interact_opt()?;
match selection {
Some(idx) => {
let (name, _, args) = COMMANDS[idx];
println!();
ui::info(&format!("Running: {name}"));
println!();
let status = std::process::Command::new(args[0])
.args(&args[1..])
.status()?;
if !status.success() {
std::process::exit(status.code().unwrap_or(1));
}
}
None => {
ui::info("Cancelled.");
}
}
Ok(())
}