use anyhow::Result;
use clap::Args;
use crate::config::Resolved;
use crate::queue;
use super::{QueueSortBy, QueueSortOrder};
#[derive(Args)]
#[command(
after_long_help = "Examples:\n ralph queue sort\n ralph queue sort --order descending\n ralph queue sort --order ascending\n ralph queue sort --dry-run\n ralph queue list --scheduled --sort-by scheduled_start --order ascending\n\nDry run:\n Shows the new queue order without modifying files.\n\nNote:\n - `ralph queue sort` reorders .ralph/queue.jsonc and intentionally supports priority only.\n - For triage/time-based sorting without mutating files, use `ralph queue list --sort-by ...`."
)]
pub struct QueueSortArgs {
#[arg(long, value_enum, default_value_t = QueueSortBy::Priority)]
pub sort_by: QueueSortBy,
#[arg(long, value_enum, default_value_t = QueueSortOrder::Descending)]
pub order: QueueSortOrder,
#[arg(long)]
pub dry_run: bool,
}
pub(crate) fn handle(resolved: &Resolved, force: bool, args: QueueSortArgs) -> Result<()> {
let _queue_lock = queue::acquire_queue_lock(&resolved.repo_root, "queue sort", force)?;
if !args.dry_run {
crate::undo::create_undo_snapshot(resolved, &format!("queue sort by {}", args.sort_by))?;
}
let mut queue_file = queue::load_queue(&resolved.queue_path)?;
let original_ids: Vec<String> = queue_file.tasks.iter().map(|t| t.id.clone()).collect();
match args.sort_by {
QueueSortBy::Priority => {
queue::sort_tasks_by_priority(&mut queue_file, args.order.is_descending());
}
}
if args.dry_run {
let new_ids: Vec<String> = queue_file.tasks.iter().map(|t| t.id.clone()).collect();
if original_ids == new_ids {
log::info!("Dry run: queue is already sorted (no changes).");
} else {
log::info!("Dry run: would reorder {} task(s).", new_ids.len());
log::info!("New order: {}", new_ids.join(", "));
}
} else {
queue::save_queue(&resolved.queue_path, &queue_file)?;
log::info!("Queue sorted by {} (order: {}).", args.sort_by, args.order);
}
Ok(())
}