use std::process::exit;
use clap::Parser;
use clap::Subcommand;
use tokio::spawn;
use crate::cmd::check::check_collection;
use crate::cmd::drill::server::AnswerControls;
use crate::cmd::drill::server::ServerConfig;
use crate::cmd::drill::server::start_server;
use crate::cmd::export::export_collection;
use crate::cmd::orphans::delete_orphans;
use crate::cmd::orphans::list_orphans;
use crate::cmd::stats::StatsFormat;
use crate::cmd::stats::print_stats;
use crate::error::Fallible;
use crate::types::timestamp::Timestamp;
use crate::utils::wait_for_server;
#[derive(Parser)]
#[command(version, about, long_about = None)]
enum Command {
Drill {
directory: Option<String>,
#[arg(long)]
card_limit: Option<usize>,
#[arg(long)]
new_card_limit: Option<usize>,
#[arg(long, default_value = "127.0.0.1")]
host: String,
#[arg(long, default_value_t = 8000)]
port: u16,
#[arg(long)]
from_deck: Option<String>,
#[arg(long)]
open_browser: Option<bool>,
#[arg(long, default_value_t = AnswerControls::Full)]
answer_controls: AnswerControls,
#[arg(long)]
bury_siblings: Option<bool>,
},
Check {
directory: Option<String>,
},
Stats {
directory: Option<String>,
#[arg(long, default_value_t = StatsFormat::Html)]
format: StatsFormat,
},
Orphans {
#[command(subcommand)]
command: OrphanCommand,
},
Export {
directory: Option<String>,
#[arg(long)]
output: Option<String>,
},
}
#[derive(Subcommand)]
enum OrphanCommand {
List {
directory: Option<String>,
},
Delete {
directory: Option<String>,
},
}
pub async fn entrypoint() -> Fallible<()> {
let cli: Command = Command::parse();
match cli {
Command::Drill {
directory,
card_limit,
new_card_limit,
host,
port,
from_deck,
open_browser,
answer_controls,
bury_siblings,
} => {
if open_browser.unwrap_or(true) {
let browser_host = host.clone();
spawn(async move {
match wait_for_server(&browser_host, port).await {
Ok(_) => {
let _ = open::that(format!("http://{browser_host}:{port}/"));
}
Err(e) => {
eprintln!("Failed to connect to server: {e}");
exit(-1)
}
}
});
}
let config = ServerConfig {
directory,
host,
port,
session_started_at: Timestamp::now(),
card_limit,
new_card_limit,
deck_filter: from_deck,
shuffle: true,
answer_controls,
bury_siblings: bury_siblings.unwrap_or(true),
};
start_server(config).await
}
Command::Check { directory } => check_collection(directory),
Command::Stats { directory, format } => print_stats(directory, format),
Command::Orphans { command } => match command {
OrphanCommand::List { directory } => list_orphans(directory),
OrphanCommand::Delete { directory } => delete_orphans(directory),
},
Command::Export { directory, output } => export_collection(directory, output),
}
}