use crate::fs::util::*;
use crate::misc::get_style;
use humantime::Duration;
use indicatif::ParallelProgressIterator;
use rayon::prelude::*;
use std::fs;
use std::io;
use std::path::PathBuf;

pub fn clean_repo(
    repo_dir: &PathBuf,
    keep_dur: Duration,
    timestamp: Option<u64>,
) -> Result<(), io::Error> {
    let dirs = setup_dirs(repo_dir, None, true, false);

    let ts = if timestamp.is_some() {
        timestamp.unwrap()
    } else {
        init_lock(repo_dir)?;
        get_ts()
    };

    let keep = keep_dur.as_secs();
    let mut rm_patches = vec![];
    for patch_path in get_patches(dirs.patches_path) {
        let patch_id = patch_path
            .file_name()
            .unwrap()
            .to_str()
            .unwrap()
            .to_string()
            .parse::<u64>()
            .unwrap();

        // once patch gets higher (newer) than threshold, break
        if patch_id > ts - keep {
            break;
        }
        rm_patches.push(patch_path.to_str().unwrap().to_string());
    }

    if !rm_patches.is_empty() {
        let style = get_style("Removing patches", rm_patches.len());
        rm_patches
            .par_iter()
            .progress_with(style)
            .map(|patch| -> Result<(), io::Error> { fs::remove_dir_all(patch) })
            .collect::<Result<(), io::Error>>()?;
    }

    Ok(())
}
