use std::fs;
use std::time::Instant;
use anyhow::Result;
use chrono::Utc;
use clap::Parser;
use log::{debug, info};
use reqwest::blocking::get;
use stderrlog::LogLevelNum::{Debug, Error, Info, Trace};
use crate::cli::Opts;
use crate::core::{prepare_data, scrape_data, to_csv};
use crate::version::version;
mod cli;
mod core;
mod version;
const PAGE: &str = "https://www.eurocontrol.int/asterix";
fn main() -> Result<()> {
let opts: Opts = Opts::parse();
if opts.version {
return Ok(());
}
let lvl = match opts.verbose {
0 => Info,
1 => Error,
2 => Debug,
3 => Trace,
_ => Trace,
};
stderrlog::new()
.modules([module_path!()])
.quiet(opts.quiet)
.verbosity(lvl)
.init()?;
info!("{}\n", version());
debug!("Debug mode engaged");
let now = Instant::now();
let doc = get(PAGE)?.text()?;
let now = now.elapsed().as_millis();
info!("Fetch took {} ms", now);
let now = Instant::now();
let areas = scrape_data(doc)?;
let now = now.elapsed().as_millis();
info!("Processing took {} ms", now);
let data: String = if opts.json {
serde_json::to_string(&areas)?
} else if opts.csv {
to_csv(prepare_data(&areas)?)?
} else {
areas
.iter()
.map(|a| format!("{a}"))
.collect::<Vec<_>>()
.join("\n")
};
match opts.output {
Some(output) => {
info!("Writing {}...", output.to_string_lossy());
fs::write(output, data)?
}
_ => println!("{}", data),
}
info!("Information retrieved on: {}", Utc::now());
Ok(())
}