//! bzippy2 — Pure-Rust BZip2 compression, part of the 7zippy umbrella.
//!
//! Phase 1: thin wrapper around the `bzip2` crate (libbzip2-rs pure-Rust backend).
//! Phase 2: native BWT+Huffman implementation.

#![deny(unsafe_op_in_unsafe_fn)]

pub mod error;

#[cfg(test)]
mod tests;

use std::io::Read;

use bzip2::read::{BzDecoder, BzEncoder};
use bzip2::Compression;

pub use error::{Bzippy2Error, Bzippy2Result};

/// Compress `input` bytes using BZip2.
///
/// `level` should be in `1..=9`; values outside this range are clamped.
///
/// # Errors
/// Returns [`Bzippy2Error::Backend`] if the bzip2 stream cannot be written.
pub fn encode(input: &[u8], level: u32) -> Bzippy2Result<Vec<u8>> {
    let level = level.clamp(1, 9);
    let compression = Compression::new(level);
    let cursor = std::io::BufReader::new(input);
    let mut encoder = BzEncoder::new(cursor, compression);
    let mut out = Vec::new();
    encoder
        .read_to_end(&mut out)
        .map_err(|e| Bzippy2Error::Backend(e.to_string()))?;
    Ok(out)
}

/// Decompress BZip2-compressed `input` bytes.
///
/// # Errors
/// Returns [`Bzippy2Error::Backend`] if the stream is corrupt or truncated.
pub fn decode(input: &[u8]) -> Bzippy2Result<Vec<u8>> {
    let mut decoder = BzDecoder::new(input);
    let mut out = Vec::new();
    decoder
        .read_to_end(&mut out)
        .map_err(|e| Bzippy2Error::Backend(e.to_string()))?;
    Ok(out)
}
