//! Synchronizes a [GOG](https://www.gog.com/) library with a local folder.

extern crate chrono;
extern crate clap;
extern crate curl;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate url;
extern crate xdg;

pub mod configfiles;
pub mod gog;
pub mod http;
mod models;

use configfiles::ConfigFiles;
use clap::{Arg, App};
use gog::Gog;
use http::Http;
use models::Config;

fn main() {
    env_logger::init().unwrap();

    let matches = App::new("Gog Synchronizer")
        .version("0.2.2")
        .author("Sebastian Hugentobler <sebastian@vanwa.ch>")
        .about("Synchronizes your gog library to a local folder.")
        .arg(Arg::with_name("game-storage")
            .short("s")
            .long("game-storage")
            .value_name("FOLDER")
            .help("Sets the download folder (defaults to the working directory).")
            .takes_value(true))
        .arg(Arg::with_name("movie-storage")
            .short("m")
            .long("movie-storage")
            .value_name("FOLDER")
            .help("Sets the download folder for movies (defaults to the working directory).")
            .takes_value(true))
        .arg(Arg::with_name("os")
            .short("o")
            .long("os")
            .value_name("FILTER")
            .help("Only sync files for this comma seperated list of operating systems.\n\
                   Valid values are 'linux', 'mac'  and 'windows'.")
            .takes_value(true))
        .arg(Arg::with_name("language")
            .short("l")
            .long("language")
            .value_name("FILTER")
            .help("Only sync files for this comma seperated list of languages.")
            .takes_value(true))
        .arg(Arg::with_name("resolution")
            .short("r")
            .long("resolution")
            .value_name("FILTER")
            .help("Only sync movies for this comma seperated list of resolutions.")
            .takes_value(true))
        .arg(Arg::with_name("skip-movies")
            .short("f")
            .long("skip-movies")
            .help("Skip movie content.")
            .takes_value(false))
        .arg(Arg::with_name("skip-games")
            .short("g")
            .long("skip-games")
            .help("Skip game content.")
            .takes_value(false))
        .get_matches();

    let configfiles = ConfigFiles::new();
    let config: Config = match configfiles.load("config.json") {
        Ok(value) => value,
        Err(_) => Config::new(),
    };

    let download_folder: &str = match matches.value_of("game-storage") {
        Some(value) => value,
        None => config.game_storage.as_str(),
    };

    let download_folder_movies: &str = match matches.value_of("movie-storage") {
        Some(value) => value,
        None => config.movie_storage.as_str(),
    };

    let os_filters: Vec<String> = match matches.value_of("os") {
        Some(value) => value.split(',').map(String::from).collect(),
        None => config.os_filters,
    };

    let language_filters: Vec<String> = match matches.value_of("language") {
        Some(value) => value.split(',').map(String::from).collect(),
        None => config.language_filters,
    };

    let resolution_filters: Vec<String> = match matches.value_of("resolution") {
        Some(value) => value.split(',').map(String::from).collect(),
        None => config.resolution_filters,
    };

    let skip_movies = if matches.is_present("skip-movies") {
        true
    } else {
        config.skip_movies
    };

    let skip_games = if matches.is_present("skip-games") {
        true
    } else {
        config.skip_games
    };

    let mut http_client = Http::new();
    let mut gog = Gog::new(&mut http_client);
    gog.login().unwrap();
    gog.sync(download_folder,
              download_folder_movies,
              &os_filters,
              &language_filters,
              &resolution_filters,
              skip_movies,
              skip_games)
        .unwrap();
}
