use std::collections::HashMap;
use std::io::{IsTerminal, Read, Write};
use std::path::Path;

use crate::BioLibApp;

pub fn run(
    app_uri: &str,
    _experiment_name: Option<&str>,
    blocking: bool,
    args: Vec<String>,
) -> crate::Result<()> {
    let app = BioLibApp::load(app_uri)?;

    let mut files = HashMap::new();
    let mut filtered_args = Vec::new();

    let mut i = 0;
    while i < args.len() {
        let arg = &args[i];
        let path = Path::new(arg);
        if path.exists() && path.is_file() {
            let mut content = Vec::new();
            std::fs::File::open(path)?.read_to_end(&mut content)?;
            let file_name = path.file_name().unwrap().to_string_lossy().to_string();
            files.insert(file_name.clone(), content);
            filtered_args.push(file_name);
        } else {
            filtered_args.push(arg.clone());
        }
        i += 1;
    }

    let mut job = app.cli(
        Some(filtered_args),
        None,
        if files.is_empty() { None } else { Some(files) },
        blocking,
    )?;

    if blocking {
        job.save_files("biolib_results", true)?;

        let exit_code = job.get_exit_code()?;

        if !std::io::stdout().is_terminal() {
            let stdout = job.get_stdout()?;
            if !stdout.is_empty() {
                std::io::stdout().write_all(&stdout)?;
            }
        }
        if !std::io::stderr().is_terminal() {
            let stderr = job.get_stderr()?;
            if !stderr.is_empty() {
                std::io::stderr().write_all(&stderr)?;
            }
        }

        if exit_code != 0 {
            std::process::exit(exit_code as i32);
        }
    } else {
        println!("{{\"job_id\": \"{}\"}}", job.id());
    }

    Ok(())
}
