Documentation
use std::process::Command;

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

use anyhow::anyhow;

pub fn samtools_bai(bam_file: &str, force: bool, threads: Option<usize>) -> anyhow::Result<()> {
    let res_filepath = format!("{}.bai", bam_file);

    let threads = threads.unwrap_or(num_cpus::get_physical() / 2);
    let threads = if threads > 1 { threads } else { 1 };

    if force {
        if path::Path::new(&res_filepath).exists() {
            fs::remove_file(&res_filepath).expect(&format!("remove {} error", res_filepath));
        }
    }

    let mut index_cmd = process::Command::new("samtools");

    index_cmd.args([
        "index",
        "-@",
        threads.to_string().as_str(),
        bam_file,
        &res_filepath,
    ]);

    if let Ok(res) = index_cmd.status() {
        if !res.success() {
            return Err(anyhow!("Run cmd error, exit status not succ: {:?}", index_cmd));
        }
    } else {
        return Err(anyhow!("Run cmd error: {:?}", index_cmd));
    }

    Ok(())
}

pub fn sort_by_coordinates(bam_file: &str, threads: Option<usize>) {
    let threads = threads.unwrap_or(num_cpus::get_physical() / 2);
    let threads = if threads > 1 { threads } else { 1 };

    let mut cmd = Command::new("samtools");
    cmd.args([
        "sort",
        "-o",
        bam_file,
        "-@",
        threads.to_string().as_str(),
        bam_file,
    ]);

    let oup = cmd.output().expect(&format!("sort {} error", bam_file));
    if !oup.status.success() {
        panic!(
            "sort {} error. {}",
            bam_file,
            String::from_utf8(oup.stderr).unwrap()
        );
    }

}