use anyhow::Result;
use clap::{Args, Subcommand};
use comfy_table::{ContentArrangement, Table};
use ironflow_sdk::IronflowClient;
use ironflow_sdk::types::{CreateScheduleRequest, ScheduleResponse};
use uuid::Uuid;
use crate::confirm::confirm;
use crate::output;
#[derive(Debug, Args)]
pub struct ScheduleArgs {
#[command(subcommand)]
pub command: ScheduleCommands,
}
#[derive(Debug, Subcommand)]
pub enum ScheduleCommands {
List,
Create {
workflow: String,
cron: String,
#[arg(long, default_value = "{}")]
inputs: String,
},
Pause {
id: Uuid,
},
Resume {
id: Uuid,
},
Delete {
id: Uuid,
#[arg(long)]
yes: bool,
},
Trigger {
id: Uuid,
},
}
fn schedules_table(schedules: &[ScheduleResponse]) -> Table {
let mut table = Table::new();
table.set_content_arrangement(ContentArrangement::Dynamic);
table.set_header(vec![
"ID",
"WORKFLOW",
"CRON",
"SOURCE",
"ENABLED",
"NEXT TRIGGER",
]);
for s in schedules {
let source = format!("{:?}", s.source).to_lowercase();
table.add_row(vec![
s.id.to_string(),
s.workflow_name.clone(),
s.cron_expression.clone(),
source.to_string(),
if s.disabled_at.is_none() {
"active".to_string()
} else {
"paused".to_string()
},
s.next_trigger_at
.as_ref()
.map(|d| d.to_string())
.unwrap_or_else(|| "-".to_string()),
]);
}
table
}
pub async fn execute(client: &IronflowClient, args: &ScheduleArgs, json_mode: bool) -> Result<()> {
match &args.command {
ScheduleCommands::List => {
let response = client.list_schedules().await?;
if json_mode {
output::print_json(&response)?;
} else {
println!("{}", schedules_table(&response.data));
}
Ok(())
}
ScheduleCommands::Create {
workflow,
cron,
inputs,
} => {
let parsed_inputs: serde_json::Value =
serde_json::from_str(inputs).map_err(|e| anyhow::anyhow!("invalid JSON: {e}"))?;
let response = client
.create_schedule(&CreateScheduleRequest {
workflow_name: workflow.clone(),
cron_expression: cron.clone(),
inputs: Some(parsed_inputs),
})
.await?;
if json_mode {
output::print_json(&response)?;
} else {
println!("Schedule {} created", response.data.id);
}
Ok(())
}
ScheduleCommands::Pause { id } => {
let response = client.pause_schedule(*id).await?;
if json_mode {
output::print_json(&response)?;
} else {
println!("Schedule {} paused", response.data.id);
}
Ok(())
}
ScheduleCommands::Resume { id } => {
let response = client.resume_schedule(*id).await?;
if json_mode {
output::print_json(&response)?;
} else {
println!("Schedule {} resumed", response.data.id);
}
Ok(())
}
ScheduleCommands::Delete { id, yes } => {
let prompt = format!("Delete schedule {id}?");
confirm(&prompt, *yes)?;
client.delete_schedule(*id).await?;
if json_mode {
output::print_json(&serde_json::json!({"deleted": id.to_string()}))?;
} else {
println!("Schedule {id} deleted");
}
Ok(())
}
ScheduleCommands::Trigger { id } => {
let response = client.trigger_schedule(*id).await?;
if json_mode {
output::print_json(&response)?;
} else {
println!("Schedule {} triggered", response.data.id);
}
Ok(())
}
}
}