use crate::parameters;
use crate::crawler;
use crate::db;
use crate::regx;
use crate::console;

use std::path::Path;
use std::fs;

const OPTION_SCAN : &str = "scan";
const OPTION_CLEAR : &str = "clear";
const OPTION_PRINT : &str = "print";
const OPTION_DIRS : &str = "dirs";

pub fn dispatch() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let p = parameters::get();

    match p.0.as_ref() {
        OPTION_SCAN => scan_directory(p.1, p.2),
        OPTION_CLEAR => clear_output(),
        OPTION_PRINT => print_duplicates(),
        OPTION_DIRS => print_empty_dirs(),
        _ => no_param()
    }
}

fn no_param() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("empty");
    Ok(())
}

fn clear_output() -> std::result::Result<(), Box<dyn std::error::Error>> {
    fs::remove_file("disk.db")?;
    Ok(())
}

fn print_empty_dirs() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let mut storage = db::Db{connection: None};
    storage.init("disk.db".to_string());
    storage.get_empty_dirs();
    Ok(())
}

fn scan_directory(scan_path : String, naming_pattern: String) -> std::result::Result<(), Box<dyn std::error::Error>> {

    let mut path = scan_path.to_string();
    if path == "none" {
        path = "/".to_string();
    }

    let mut storage = db::Db{connection: None};
    storage.init("disk.db".to_string());

    // cleanup
    if storage.has_entries() {
        println!("Database is not empty. Do you want to drop existing entries? [y/n]");
        let answer = console::input().to_lowercase();
    
        if answer == "y" {
            storage.erase();
        }
    }

    let mut crawler = crawler::Crawler{
        _inx: i64::min_value() +1,
        _storage: storage
    };

    let mut rx = regx::Rgx{
        _pattern : naming_pattern,
        _regex : None,
        _initialized : false
    };

    crawler.read_dir_my(Path::new(&path), &mut rx)?;
    Ok(())
}

fn print_duplicates() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("Printing");
    let mut storage = db::Db{connection: None};
    storage.init("disk.db".to_string());
    storage.get_duplicates();
    Ok(())
}
