//! # bunbun
//!
//! Fast, unified genotype parser for PLINK, VCF, PLINK2, and BGEN formats.

pub mod core;
pub mod error;
pub mod formats;
pub mod io;
mod python;

pub use core::{GenotypeChunk, GenotypeData};
pub use error::{BunbunError, Result};
pub use formats::{BgenReader, PlinkReader, Plink2Reader, VcfReader};
pub use io::{ChunkedReader, GenotypeReader};

/// Read any supported genotype format with auto-detection.
pub fn read(path: impl AsRef<std::path::Path>) -> Result<GenotypeData> {
    let path = path.as_ref();
    let format = io::FormatDetector::detect(path)?;
    let reader: Box<dyn GenotypeReader> = match format {
        io::Format::Plink => Box::new(PlinkReader::new(path)),
        io::Format::Plink2 => Box::new(Plink2Reader::new(path)),
        io::Format::Vcf => Box::new(VcfReader::new(path)),
        io::Format::Bgen => Box::new(BgenReader::new(path)),
    };
    reader.read_all()
}

/// Stream any supported format in chunks of `chunk_size` variants.
pub fn stream(
    path: impl AsRef<std::path::Path>,
    chunk_size: usize,
) -> Result<ChunkedReader> {
    let path = path.as_ref();
    let format = io::FormatDetector::detect(path)?;
    let reader: Box<dyn GenotypeReader> = match format {
        io::Format::Plink => Box::new(PlinkReader::new(path)),
        io::Format::Plink2 => Box::new(Plink2Reader::new(path)),
        io::Format::Vcf => Box::new(VcfReader::new(path)),
        io::Format::Bgen => Box::new(BgenReader::new(path)),
    };
    reader.read_chunked(chunk_size)
}

// ── PyO3 module ──────────────────────────────────────────────────

use pyo3::prelude::*;

#[pymodule]
fn _native(m: &Bound<'_, PyModule>) -> PyResult<()> {
    python::register_module(m)?;
    Ok(())
}
