use std::io::{self, Write};
use clap::Parser;
use tasg::{
cli::{Cli, Commands},
error::TaskError,
store::{JsonStore, Store},
};
fn get_default_tasks_file() -> std::path::PathBuf {
let mut path = dirs::config_dir().expect("Failed to determine configuration directory");
path.push("tasg");
std::fs::create_dir_all(&path).expect("Failed to create configuration directory");
path.push("tasks.json");
path
}
fn ensure_tasks_file_exists(path: &str) -> Result<(), TaskError> {
let path = std::path::Path::new(path);
if !path.exists() {
std::fs::create_dir_all(path.parent().unwrap())?;
std::fs::File::create(path)?;
std::fs::write(path, "[]")?;
}
Ok(())
}
fn run(cli: Cli, store: JsonStore) -> Result<(), TaskError> {
match cli.command {
Commands::Add { description } => {
if description.trim().is_empty() {
return Err(TaskError::InvalidInput("Description cannot be empty".into()));
}
let id = store.list(true)?.len() as u32 + 1;
let task = tasg::task::Task::new(id, description);
store.add(task)?;
}
Commands::List { all } => {
let tasks = store.list(all)?;
if tasks.is_empty() {
println!("No tasks found");
} else {
println!(
"{:<5} {:<50} {:<20} {}",
"ID",
"Description",
"Created At",
if all { "Completed" } else { "" }
);
for task in tasks {
println!(
"{:<5} {:<50} {:<20} {}",
task.id,
task.description,
task.created_at.format("%Y-%m-%d %H:%M:%S"),
if all {
if task.completed {
"Yes"
} else {
"No"
}
} else {
""
}
);
}
}
}
Commands::Complete { id } => {
store.complete(id)?;
}
Commands::Delete { id } => {
store.delete(id)?;
}
Commands::Nuke => {
print!(
"Are you sure you want to delete all tasks? This action cannot be undone. (y/N): "
);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
if input.trim().to_lowercase() == "y" {
std::fs::remove_file(store.path())?;
println!("All tasks have been deleted.");
} else {
println!("Operation cancelled.");
}
}
Commands::Edit { id, description } => {
store.edit(id, description)?;
}
}
Ok(())
}
fn main() {
let tasks_file = std::env::var("TASG_FILE")
.unwrap_or_else(|_| get_default_tasks_file().to_string_lossy().to_string());
if let Err(e) = ensure_tasks_file_exists(&tasks_file) {
eprintln!("Error: {}", e);
std::process::exit(1);
}
let store = JsonStore::new(tasks_file);
let cli = Cli::parse();
if let Err(e) = run(cli, store) {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}