use {
    rand::Rng,
    std::{
        env,
        fs::{self, DirEntry},
        io::{self, Write},
        path::PathBuf,
    },
};

fn get_datadirs() -> Vec<PathBuf> {
    let mut dirs = match env::var("XDG_DATA_DIRS") {
        Ok(dirs) => dirs
            .split(':')
            .map(PathBuf::from)
            .map(|mut p| {
                p.push("42");
                p
            })
            .collect(),
        Err(_) => vec![
            PathBuf::from("/usr/local/share/42"),
            PathBuf::from("/usr/share/42"),
        ],
    };
    if let Ok(home) = env::var("HOME") {
        let hddir = [&home, ".local", "share", "42"].iter().collect();
        dirs.push(hddir);
    }
    dirs
}

fn is_file(entry: &DirEntry) -> bool {
    if let Ok(t) = entry.file_type() {
        if t.is_file() {
            return true;
        }
    }
    false
}

fn get_files() -> Vec<PathBuf> {
    let mut files = vec![];
    get_datadirs().iter().for_each(|d| {
        if d.exists() {
            if let Ok(dir) = fs::read_dir(&d) {
                dir.filter(|e| e.is_ok())
                    .filter(|e| is_file(e.as_ref().unwrap()))
                    .map(|e| e.unwrap().path())
                    .for_each(|f| files.push(f));
            }
        }
    });
    files
}

fn main() -> Result<(), io::Error> {
    let files = get_files();
    let len = files.len();
    let mut rng = rand::thread_rng();
    let idx = rng.gen_range(0..len);
    if let Some(path) = files.get(idx) {
        let contents = fs::read(path)?;
        io::stdout().write_all(&contents)?;
    }
    Ok(())
}
