use anyhow::Result;
use clap::{crate_authors, crate_version, AppSettings, Parser};
use d7sneakers::{Constraints, SneakerWorld};
extern crate pretty_env_logger;
#[macro_use]
extern crate log;
#[derive(Parser)]
#[clap(version = crate_version!(), author = crate_authors!())]
struct Opts {
#[clap(short, long, default_value = "/tmp/d7sneaker")]
basedir: String,
#[clap(short, long, parse(from_occurrences))]
verbose: i32,
#[clap(subcommand)]
subcmds: SubCommand,
}
#[derive(Parser)]
enum SubCommand {
Add(Add),
Sys(Sys),
Query(Query),
}
#[derive(Parser)]
struct Add {
#[clap(short = 'H', long)]
hex: Option<String>,
#[clap(short, long)]
path: Option<String>,
#[clap(short, long)]
recursive: bool,
}
#[derive(Parser)]
struct Sys {
#[clap(short, long)]
fs: bool,
#[clap(short, long)]
db: bool,
}
#[derive(Parser)]
struct Query {
#[clap(short, long)]
ids: bool,
#[clap(short, long)]
print_infos: Option<String>,
#[clap(short, long)]
forward: bool,
#[clap(short, long)]
dispatch: bool,
#[clap(short, long)]
reassembly: bool,
#[clap(short, long)]
contra: bool,
#[clap(short, long)]
local: bool,
#[clap(short, long)]
all_constraints: bool,
#[clap(short, long)]
query_node: Option<String>,
#[clap(short = 'F', long)]
filter_service: Option<String>,
#[clap(short, long)]
group_destinations: Option<String>,
}
fn main() -> Result<()> {
let opts: Opts = Opts::parse();
match opts.verbose {
0 => std::env::set_var("RUST_LOG", ""),
1 => std::env::set_var("RUST_LOG", "d7sneakers=info"),
2 | _ => std::env::set_var("RUST_LOG", "d7sneakers=debug"),
}
pretty_env_logger::init_timed();
debug!("Value for basedir: {}", opts.basedir);
let sneakers = SneakerWorld::open(&opts.basedir)?;
match opts.subcmds {
SubCommand::Add(a) => {
if let Some(input) = a.hex {
let (bndl, bundle_size, path) = sneakers.fs.import_hex(&input)?;
sneakers.db.insert(&bndl, bundle_size, Some(path))?;
} else if let Some(path) = a.path {
sneakers.import_dir(&path, a.recursive)?;
}
}
SubCommand::Sys(m) => {
if m.db && m.fs {
sneakers.sync()?;
} else if m.db {
sneakers.db.sync_with_fs(&sneakers.fs)?;
} else if m.fs {
sneakers.fs.sync_to_db(&sneakers.db)?;
}
}
SubCommand::Query(q) => {
if q.ids {
println!("{:#?}", sneakers.db.ids());
} else if q.print_infos.is_some() {
let bid = q.print_infos.unwrap();
println!("{:#?}", sneakers.db.get_bundle_entry(&bid).unwrap());
println!("{:#?}", sneakers.db.get_constraints(&bid).unwrap());
} else if q.all_constraints {
println!("{:#?}", sneakers.db.all_constraints());
} else if q.forward {
println!(
"{:#?}",
sneakers.db.filter_constraints(Constraints::FORWARD_PENDING)
);
} else if q.dispatch {
println!(
"{:#?}",
sneakers
.db
.filter_constraints(Constraints::DISPATCH_PENDING)
);
} else if q.reassembly {
println!(
"{:#?}",
sneakers
.db
.filter_constraints(Constraints::REASSEMBLY_PENDING)
);
} else if q.contra {
println!(
"{:#?}",
sneakers.db.filter_constraints(Constraints::CONTRAINDICATED)
);
} else if q.local {
println!(
"{:#?}",
sneakers.db.filter_constraints(Constraints::LOCAL_ENDPOINT)
);
} else if let Some(node) = q.query_node {
if let Some(service) = q.filter_service {
println!(
"{:#?}",
sneakers.db.filter_node_and_service(&node, &service)
);
} else {
println!("{:#?}", sneakers.db.filter_node(&node));
}
} else if let Some(service) = q.filter_service {
println!("{:#?}", sneakers.db.filter_service(&service));
} else if let Some(service) = q.group_destinations {
println!("{:#?}", sneakers.db.filter_groups(&service));
}
}
}
Ok(())
}