use crate::config::workflows::WorkflowsConfig;
use anyhow::Result;
use serde_json::{Value, json};
pub fn list_workflows(workflows: &WorkflowsConfig) -> Result<Value> {
let mut workflow_list: Vec<Value> = Vec::new();
for (name, config) in &workflows.named_workflows {
let source = config.source_file.as_ref().map(|p| p.display().to_string());
workflow_list.push(json!({
"name": name,
"description": config.description,
"source_file": source,
"states": config.states.keys().collect::<Vec<_>>(),
"phases": config.phases.keys().collect::<Vec<_>>(),
}));
}
workflow_list.sort_by(|a, b| {
a.get("name")
.and_then(|v| v.as_str())
.unwrap_or("")
.cmp(b.get("name").and_then(|v| v.as_str()).unwrap_or(""))
});
let default_workflow = workflows.default_workflow_key.as_ref();
Ok(json!({
"workflows": workflow_list,
"default_workflow": default_workflow,
"count": workflows.named_workflows.len(),
}))
}
pub fn get_workflow(workflows: &WorkflowsConfig, name: &str) -> Result<Value> {
let config = workflows
.named_workflows
.get(name)
.ok_or_else(|| anyhow::anyhow!("Workflow '{}' not found", name))?;
let source = config.source_file.as_ref().map(|p| p.display().to_string());
let states: Vec<Value> = config
.states
.iter()
.map(|(state_name, state)| {
json!({
"name": state_name,
"exits": state.exits,
"timed": state.timed,
"has_enter_prompt": state.prompts.enter.is_some(),
"has_exit_prompt": state.prompts.exit.is_some(),
})
})
.collect();
let phases: Vec<Value> = config
.phases
.iter()
.map(|(phase_name, phase)| {
json!({
"name": phase_name,
"has_enter_prompt": phase.prompts.enter.is_some(),
"has_exit_prompt": phase.prompts.exit.is_some(),
})
})
.collect();
Ok(json!({
"name": name,
"description": config.description,
"source_file": source,
"settings": {
"initial_state": config.settings.initial_state,
"disconnect_state": config.settings.disconnect_state,
"blocking_states": config.settings.blocking_states,
},
"states": states,
"phases": phases,
"combo_count": config.combos.len(),
}))
}