use std::env;
use std::path::Path;

struct DirInfo {
    size: u64,
    depth: u32
}

const EMPTY: DirInfo = DirInfo {size: 0, depth: 0};

fn main() {
    let arg = env::args_os().nth(1).expect("Please, provide a file as argument");
    let path = Path::new(&arg);
    if path.is_dir() {
        let info = dir_info(path);
        println!("size:\t{} bytes\ndepth:\t{} ", info.size, info.depth - 1);
    } else {
        println!("{} is not a directory", arg.to_str().expect("Fatal"));
    }
}

fn update_info(info: DirInfo, path: &Path) -> DirInfo {
    let child_info = dir_entry_info(path);
    let new_size = info.size + child_info.size;
    let new_depth = std::cmp::max(info.depth, 1 + child_info.depth);
    DirInfo {size: new_size, depth: new_depth}
}

fn 
(path: &Path) -> DirInfo {
    if path.is_file() {
        file_info(path)
    } else if path.is_dir() {
        dir_info(path)
    } else {
        EMPTY
    }
}

fn file_info(path: &Path) -> DirInfo {
    let metadata = path.metadata().ok().expect("Cannot get file metadata");
    DirInfo {size: metadata.len(), depth: 0} 
}

fn dir_info(path: &Path) -> DirInfo {
    match std::fs::read_dir(path) {
        Err(_) =>  EMPTY,
        Ok(entries) =>
            entries.fold(EMPTY,
                |info, entry| update_info(info, &entry.unwrap().path()))
    }
}

dir_entry_info