//! JBIG2Decode Filter Implementation
//!
//! Uses the pure-Rust `hayro-jbig2` crate for ITU T.88 decoding.

use super::params::JBIG2DecodeParams;
use crate::fitz::error::{Error, Result};

/// Decode JBIG2 compressed data.
///
/// PDF embeds JBIG2 in "embedded" organisation (Annex D.3 of T.88).
/// Global symbol dictionary segments may be provided via `params`.
#[cfg(feature = "jbig2")]
pub fn decode_jbig2(data: &[u8], params: Option<&JBIG2DecodeParams>) -> Result<Vec<u8>> {
    let globals = params.and_then(|p| p.jbig2_globals.as_deref());

    let image = hayro_jbig2::decode_embedded(data, globals)
        .map_err(|e| Error::Generic(format!("JBIG2Decode failed: {:?}", e)))?;

    let width = image.width as usize;
    let height = image.height as usize;
    let bytes_per_row = width.div_ceil(8);
    let mut output = vec![0u8; bytes_per_row * height];

    for y in 0..height {
        for x in 0..width {
            let idx = y * width + x;
            if idx < image.data.len() && image.data[idx] {
                output[y * bytes_per_row + x / 8] |= 1 << (7 - (x % 8));
            }
        }
    }

    Ok(output)
}

#[cfg(not(feature = "jbig2"))]
pub fn decode_jbig2(_data: &[u8], _params: Option<&JBIG2DecodeParams>) -> Result<Vec<u8>> {
    Err(Error::Generic(
        "JBIG2 support not enabled. Enable 'jbig2' feature.".into(),
    ))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    #[cfg(not(feature = "jbig2"))]
    fn test_jbig2_disabled() {
        let data = &[0u8; 100];
        let result = decode_jbig2(data, None);
        assert!(result.is_err());
        let err = result.unwrap_err().to_string();
        assert!(err.contains("jbig2"));
    }

    #[test]
    #[cfg(feature = "jbig2")]
    fn test_jbig2_invalid_data() {
        let data = &[0u8; 10];
        let result = decode_jbig2(data, None);
        assert!(result.is_err());
    }

    #[test]
    #[cfg(feature = "jbig2")]
    fn test_jbig2_with_globals() {
        let params = JBIG2DecodeParams {
            jbig2_globals: Some(vec![0u8; 10]),
        };
        let result = decode_jbig2(&[0u8; 10], Some(&params));
        assert!(result.is_err()); // Invalid data, but globals path is exercised
    }
}
