use std::{fs, path::Path, process::Command};

const FILE_ENDINGS: &'static [&'static str] = &[
    "vert", "frag", "geom", "comp", "rchit", "rmiss", "rgen", "rahit",
];

fn find_shader_files(path: impl AsRef<Path>) -> Vec<String> {
    let mut v = Vec::new();

    if !path.as_ref().is_dir() {
        panic!("path ({:?}) is not a directory!", path.as_ref());
    }

    for entry in fs::read_dir(path).unwrap() {
        let child_path = entry.unwrap().path();

        if child_path.is_dir() {
            v.extend(find_shader_files(child_path));
        } else if child_path.is_file() {
            for ending in FILE_ENDINGS.iter() {
                if child_path.extension().unwrap() == *ending {
                    v.push(child_path.to_str().unwrap().to_string());

                    break;
                }
            }
        }
    }

    v
}

fn compile_shader(shader_files: &[String]) {
    Command::new("glslangValidator")
        .arg("--help")
        .output()
        .expect("Failed to execute glslangValidator. Maybe you need to install it first?");

    for shader in shader_files {
        Command::new("glslangValidator")
            .arg("-V")
            .arg(shader)
            .arg("-o")
            .arg(&format!("{}.spv", shader))
            .output()
            .expect(&format!("Failed to compile {}", shader));
    }
}

fn main() {
    let shader_files = find_shader_files("src");
    compile_shader(&shader_files);
}