use tokio::process::Command;

pub async fn collect() {
    collect_dir_output("audio_engine", "../collect_audio_engine.txt").await;
    //collect_dir_output("firmware", "../collect_firmware.txt").await;
    collect_dir_output("gui", "../collect_gui.txt").await;
    collect_dir_output("osc", "../collect_osc.txt").await;
    collect_dir_output("simulator", "../collect_simulator.txt").await;
    collect_dir_output("xtask", "../collect_xtask.txt").await;
    collect_image_output("./collect_image.txt").await;
}

pub async fn collect_dir_output(dir: &str, output: &str) {
    #[cfg(target_os = "windows")]
    let bash = "C:\\Program Files\\Git\\git-bash.exe";
    #[cfg(target_os = "linux")]
    let bash = "bash";

    Command::new(bash)
        .current_dir(dir)
        .arg("-c")
        .arg(format!("../collect.sh -s core -o {output}"))
        .output()
        .await
        .expect("Failed to collect audio_engine sources");
}

pub async fn collect_image_output(output: &str) {
    use std::fs;

    let mut content = String::new();
    content.push_str("File Contents:\n");

    // Collect specific files mentioned by user
    let files_to_collect = vec![
        "image/conf/bblayers.conf",
        "image/conf/local.conf",
        "image/conf/templateconf.cfg",
        "image/docker-compose.yml",
        "image/Dockerfile",
        "image/implementation_plan.md",
        "image/run",
    ];

    for file_path in files_to_collect {
        if let Ok(file_content) = fs::read_to_string(file_path) {
            content.push_str(&format!("\n===== FILE: {} =====\n", file_path));
            content.push_str(&file_content);
        }
    }

    // Collect meta-fcb-looper files
    if fs::read_dir("image/meta-layers/meta-fcb-looper").is_ok() {
        collect_directory_recursive("image/meta-layers/meta-fcb-looper", &mut content);
    }

    // Write to output file
    if let Err(e) = fs::write(output, content) {
        eprintln!("Failed to write output file: {}", e);
    } else {
        println!("Successfully collected image files to {}", output);
    }
}

fn collect_directory_recursive(dir_path: &str, content: &mut String) {
    use std::fs;

    if let Ok(entries) = fs::read_dir(dir_path) {
        for entry in entries.flatten() {
            let path = entry.path();
            if path.is_file() {
                let file_path = path.to_string_lossy();
                if file_path.ends_with(".bb")
                    || file_path.ends_with(".bbappend")
                    || file_path.ends_with(".conf")
                    || file_path.ends_with(".wks")
                    || file_path.ends_with(".service")
                {
                    if let Ok(file_content) = fs::read_to_string(&path) {
                        content.push_str(&format!("\n===== FILE: {} =====\n", file_path));
                        content.push_str(&file_content);
                    }
                }
            } else if path.is_dir() {
                collect_directory_recursive(&path.to_string_lossy(), content);
            }
        }
    }
}
