use console::Key::*;
use std::{io, sync::{Arc, atomic::{AtomicBool, Ordering}}};
use clap::{crate_authors, crate_version, App, Arg};
use gcd_cli::config::Config;
use gcd_cli::db::Database;
use gcd_cli::inputhandler::InputHandler;
use gcd_cli::outputhandler::OutputHandler;
use gcd_cli::scriptfile::ScriptFile;
use gcd_cli::constants::*;
fn main() -> io::Result<()> {
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler( move || {
r.store(false, Ordering::SeqCst);
}).expect("Error setting Ctrl-C handler");
let config = Config::new();
let default_projects_dir = config.projects_dir();
let default_script_file = config.script_file();
let default_database_file = config.database_file();
let matches = App::new("gcd-select")
.version(&crate_version!()[..])
.author(crate_authors!())
.about("Select a project.")
.arg(
Arg::with_name(PROJECTS_DIR)
.short("p")
.long(PROJECTS_DIR)
.env(PROJECTS_DIR)
.value_name(PROJECTS_DIR_VALUE_NAME)
.default_value(&default_projects_dir)
.help(PROJECTS_DIR_HELP)
.required(false)
.takes_value(true),
)
.arg(
Arg::with_name(SCRIPT_FILE)
.short("s")
.long(SCRIPT_FILE)
.env(SCRIPT_FILE)
.value_name(SCRIPT_FILE_VALUE_NAME)
.default_value(&default_script_file)
.help(SCRIPT_FILE_HELP)
.required(false)
.takes_value(true),
)
.arg(
Arg::with_name(DATABASE_FILE)
.short("d")
.long(DATABASE_FILE)
.env(DATABASE_FILE)
.value_name(DATABASE_FILE_VALUE_NAME)
.default_value(&default_database_file)
.help(DATABASE_FILE_HELP)
.required(false)
.takes_value(true),
)
.arg(
Arg::with_name(EXEC_COMMAND)
.long(EXEC_COMMAND)
.value_name(EXEC_COMMAND_VALUE_NAME)
.help(EXEC_COMMAND_HELP)
.required(false)
.takes_value(true)
.multiple(true)
.value_delimiter(" ")
.value_terminator(";"),
)
.arg(Arg::with_name(FIND).help(FIND_HELP))
.get_matches();
let script_file = matches
.value_of(SCRIPT_FILE)
.unwrap_or(&default_script_file)
.to_string();
let database_file = matches
.value_of(DATABASE_FILE)
.unwrap_or(&default_database_file)
.to_string();
let projects_dir = matches
.value_of(PROJECTS_DIR)
.unwrap_or(&default_projects_dir)
.to_string();
let param = matches.value_of(FIND).unwrap_or("");
let mut input = InputHandler::new(¶m);
let mut output = OutputHandler::new(projects_dir);
let scriptfile = ScriptFile::new(script_file);
let database = Database::new(database_file);
println!("");
if param.len() != 0 {
let count = output.show_results(database.find(input.line.clone()))?;
if count == 1 {
if let Some(result) = output.get_selected() {
if let Some(command) = matches.values_of(EXEC_COMMAND) {
scriptfile
.write_cd_and_exec(result, command.map(|c| c.to_string()).collect())?;
} else {
scriptfile.write_cd_only(result)?;
}
return Ok(());
}
}
} else {
let _ = output.show_results(database.find(".*".to_string()));
}
while running.load(Ordering::SeqCst) {
match input.read_key()? {
Enter => {
if let Some(result) = output.get_selected() {
database.increment(result.clone());
if let Some(command) = matches.values_of(EXEC_COMMAND) {
scriptfile
.write_cd_and_exec(result, command.map(|c| c.to_string()).collect())?;
} else {
scriptfile.write_cd_only(result)?;
}
}
break;
}
ArrowUp => {
output.up()?;
}
ArrowDown => {
output.down()?;
}
Escape => {
break;
}
_ => {
output.show_results(database.find(input.line.clone()))?;
}
}
}
output.clear_results()?;
Ok(())
}