use crate::{diff, fs::util::*};
use rayon::prelude::*;
use std::fs;
use std::io;
use std::path::PathBuf;
use std::process::exit;

pub fn init_repo(
    repo_dir: &PathBuf,
    data_dir: &PathBuf,
    ignore_file: &Option<PathBuf>,
) -> Result<(), io::Error> {
    let dirs = setup_dirs(repo_dir, Some(data_dir), false, true);
    fs::create_dir(dirs.repo_dir.clone())?;
    init_lock(repo_dir)?;

    fs::create_dir(dirs.repo_base.clone())?;
    fs::create_dir(dirs.patches_path)?;

    if let Some(file) = ignore_file {
        if !PathBuf::from(file).exists() {
            println!("Ignore file doesn't exist, exiting");
            fs::remove_dir_all(dirs.repo_dir)?;
            exit(1);
        }
        fs::copy(file, dirs.ignore_path.clone())?;
    }

    let data_paths = get_walk(&dirs.data_dir.as_ref().unwrap(), &dirs.ignore_path)?;

    copy_dir_all(
        &dirs.data_dir.clone().unwrap(),
        &data_paths.iter().collect(),
        &dirs.repo_base,
        false,
        false,
        true,
    )?;

    let mut hashes = diff::hash::create_hashes(
        &data_paths.into_par_iter().filter(|p| p.is_file()).collect(),
        &dirs.data_dir.unwrap(),
        false,
    )?;

    diff::hash::write_hashes(&dirs.hash_path, &mut hashes)?;

    Ok(())
}
