use std::fs::{File, read_to_string};

pub fn parse_wgsl(source: &String) -> naga::Module {
    // Create Parser
    let mut parser = naga::front::wgsl::Parser::new();

    // Create empty Module
    let mut module = naga::Module::default();
    
    // Attempt to parse the source code
    let module_result = parser.parse(source.as_str());
    match module_result {
        Ok(in_mod) => {
            //println!("{:?}", in_mod);
            module = in_mod;
        },
        Err(error) => { println!("Parsing error:\n{}", error) }
    }

    // Return the Module
    module
}

pub fn generate_wgsl(module: &naga::Module) -> String {
    // Create options for the Writer
    let wgsl_flags = naga::back::wgsl::WriterFlags::empty();

    // Create a string buffer for the Writer to use
    let mut wgsl_buffer = String::new();

    // Create validator (to check if module is OK)
    let mut validator = naga::valid::Validator::new(naga::valid::ValidationFlags::empty(), naga::valid::Capabilities::empty());

    // Get ModuleInfo (produced by a syntax validator)
    let module_info = validator.validate(&module).unwrap();

    // Create the Writer itself
    let mut wgsl_writer = naga::back::wgsl::Writer::new(&mut wgsl_buffer, wgsl_flags);

    // Attempt to write
    wgsl_writer.write(&module, &module_info).expect("wgsl write failed");
    
    wgsl_buffer
}

pub fn add_includes(source: &String) -> String {
    let mut combined = String::new();

    let source_lines = source.lines();
    for line in source_lines {
        // Get a vector of the words in the line
        let mut words: Vec<&str> = line.split(" ").collect();

        // Check if this is an include statement
        if words[0] == "#include" {
            // Get the rest of the line
            words.remove(0);
            let file_path: String = words.join(" ");

            // Get the code from the included file
            let included = read_to_string(file_path).unwrap();

            combined = format!("{}\n{}", combined, included);
        } else {
            combined = format!("{}\n{}", combined, line);
        }
    }

    combined
}