mod ios;

use std::env;
use std::fs;
use std::io::{Error, ErrorKind};
use std::path::{Path, PathBuf};
use std::process::exit;

use clap::{App, AppSettings, Arg};
use photon_rs::colour_spaces::{darken_hsl, lighten_hsl};
use photon_rs::native::{open_image, save_image};
use photon_rs::PhotonImage;
use photon_rs::transform::resize;
use photon_rs::transform::SamplingFilter::Lanczos3;
use walkdir::WalkDir;

trait AddArgs {
    fn add_lighten_dark_filename(self) -> Self;
}

impl AddArgs for App<'static> {
    fn add_lighten_dark_filename(mut self) -> Self {
        self
            .arg(Arg::new("lighten")
                .long("lighten")
                .short('l')
                .takes_value(true)
                .conflicts_with("darken")
                .default_value("0.4")
            )
            .arg(Arg::new("darken")
                .long("darken")
                .short('d')
                .takes_value(true)
                .conflicts_with("lighten")
            )
            .arg(Arg::new("force")
                .long("force")
                .short('f')
                .takes_value(false)
            )
            .arg(Arg::new("output")
                .long("output")
                .short('o')
                .takes_value(true)
            )
            .arg(Arg::new("icon_fpath")
                .required(true)
            )
    }
}

const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = env!("CARGO_PKG_NAME");


fn main() -> Result<(), Error> {
    let matches = App::new(NAME)
        .version(VERSION)
        .about("Generate icon sets from a single image.")
        .setting(AppSettings::ArgRequiredElseHelp)
        .subcommand(App::new("ios")
            .add_lighten_dark_filename()
        )
        .subcommand(App::new("web")
            .add_lighten_dark_filename()
        )
        .get_matches();

    match matches.subcommand().unwrap() {
        ("ios", matches) => {
            let output = matches.value_of("output")
                .map(|s| PathBuf::from(s))
                .unwrap_or_else(|| ios::find_assets_dir()
                    .expect("Could not find Assets.xcassets directory. Please supply output fpath manually with -o.")
                );
            let icon_fpath = matches.value_of("icon_fpath").unwrap();
            ios::run(
                icon_fpath,
                &output,
                matches.value_of("darken")
                    .map(|f| -f.parse::<f32>().expect("Failed to parse darken value as float."))
                    .unwrap_or(matches.value_of("lighten").unwrap()
                        .parse::<f32>()
                        .expect("Failed to parse lighten value as float.")
                    ),
                matches.is_present("force"),
            ).map_err(|e| {
                eprintln!("{}", e);
                exit(1);
            });
        }
        ("web", matches) => {
            unimplemented!()
        }
        _ => panic!("Unknown subcommand."),
    }

    Ok(())
}