use std::error::Error;
use std::path::Path;
use std::process::exit;
use std::fs::create_dir_all;

use glob::{glob_with, MatchOptions};
use image::imageops::FilterType;
use rayon::prelude::*;

fn main() -> Result<(), Box<dyn Error>> {
    let options: MatchOptions = Default::default();
    let files: Vec<_> = glob_with("*.jpg", options)?
        .filter_map(|x| x.ok())
        .collect();

    if files.len() == 0 {
        println!("No .jpg files found in current directory");
        exit(1);
    }

    let thumb_dir = "thumbnails";
    create_dir_all(thumb_dir)?;

    println!("Saving {} thumbnails into '{}'...", files.len(), thumb_dir);

    let image_failures: Vec<_> = files
        .par_iter()
        .map(|path| {
            make_thumbnail(path, thumb_dir, 100)
                .map_err(|e| println!("{e}: path: {}", path.display()))
        })
        .filter_map(|x| x.err())
        .collect();

    println!("{} thumbnails saved successfully", files.len() - image_failures.len());
    Ok(())
}

fn make_thumbnail<PA, PB>(original: PA, thumb_dir: PB, longest_edge: u32) -> Result<(), Box<dyn Error>>
where
    PA: AsRef<Path>,
    PB: AsRef<Path>,
{
    let img = image::open(original.as_ref())?;
    let file_path = thumb_dir.as_ref().join(original);

    Ok(img.resize(longest_edge, longest_edge, FilterType::Nearest)
        .save(file_path)?)
}
