md_analysis 0.2.1

molecular dynamics
// //! 分子动力学分析工具
// //!
// //! 读取 BAM 文件中的 dw/ar 字段(PacBio subread attributes),
// //! 截断到最大值 10000,分 bin (0~10000) 计数并输出 CSV。
// //!
// //! 支持:读长过滤、位置切片、ACGT 分碱基统计。
// //!
// //! 采用三阶段 worker 流水线架构(reader → stats workers → writer),
// //! 通过线程间通道实现并行 binning,writer 端 sequential merge 汇总结果。

mod bam_record_ext;
mod binning;
mod cli;
mod config;
mod pbar;
mod pipelines;
mod range;
mod reader;
mod record;
mod writer;

use std::path::Path;

use anyhow::Result;
use clap::Parser;
use config::default_worker_count;
use pipelines::PipelineConfig;

use crate::range::Range;
// use writer::write_single_csv;

fn main() -> Result<()> {
    let args = cli::CliArgs::parse();

    if !Path::new(&args.bam_file).exists() {
        eprintln!("错误: 找不到文件 '{}'", args.bam_file);
        std::process::exit(1);
    }

    println!("处理 BAM: {}", args.bam_file);

    let worker_count = if args.workers > 0 {
        args.workers
    } else {
        default_worker_count()
    };

    let pipeline_cfg = PipelineConfig::new(worker_count);

    let out_dir: String = Path::new(&args.bam_file)
        .parent()
        .map(|d| d.to_str().unwrap_or(""))
        .unwrap_or(".")
        .to_string();
    let bam_name = Path::new(&args.bam_file)
        .file_stem()
        .unwrap()
        .to_str()
        .unwrap()
        .to_string();

    match args.commands {
        cli::Commands::RawBam(raw_bam_args) => {
            pipelines::raw_bam_pipeline::run_pipeline(
                &args.bam_file,
                &pipeline_cfg,
                raw_bam_args.slice_n,
                &out_dir,
                &bam_name,
            );
        }

        cli::Commands::AlignedBam(aligned_bam_args) => {
            let range = Range::<usize>::new(&aligned_bam_args.ref_range);
            pipelines::aligned_bam_pipeline::run_pipeline(
                &args.bam_file,
                &pipeline_cfg,
                &range,
                &out_dir,
                &bam_name,
            );
        }
    }
    // 通过流水线并行处理(支持 per-base + slicing + 长度过滤)

    Ok(())
}