#![deny(warnings)]
#![allow(dead_code)]
//! [TSM.ID].[11031972] -- Platform X Ecosystem
//! xcu-watermark -- Holographic Video Frame Watermark Embedder
#[derive(Debug)] pub enum WmError { InvalidFrame(String), ExtractionFailed(String) }
impl std::fmt::Display for WmError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::InvalidFrame(e)|Self::ExtractionFailed(e) => write!(f, "{e}") } } }
impl std::error::Error for WmError {}
#[derive(Debug, Clone, Copy)] pub enum EmbedStrength { Fragile, SemiRobust, Robust }
impl EmbedStrength { pub fn bits_per_pixel(&self) -> u8 { match self { Self::Fragile => 1, Self::SemiRobust => 2, Self::Robust => 3 } } }
pub struct WatermarkEncoder;
impl WatermarkEncoder {
    pub fn embed(pixels: &mut [u8], data: &[u8], strength: EmbedStrength) -> Result<usize, WmError> {
        if pixels.is_empty() { return Err(WmError::InvalidFrame("Empty".into())); }
        let bits_pp = strength.bits_per_pixel();
        let mask = !(((1u8 << bits_pp) - 1) as u8);
        let mut bits_written = 0usize;
        for &byte in data {
            for bit_idx in 0..8 {
                let pi = bits_written; if pi >= pixels.len() { return Ok(bits_written); }
                let bit = (byte >> (7 - bit_idx)) & 1;
                pixels[pi] = (pixels[pi] & mask) | (bit & ((1 << bits_pp) - 1));
                bits_written += 1;
            }
        }
        Ok(bits_written)
    }
    pub fn extract(pixels: &[u8], data_len: usize, strength: EmbedStrength) -> Result<Vec<u8>, WmError> {
        if pixels.is_empty() { return Err(WmError::ExtractionFailed("Empty".into())); }
        let mask = ((1u8 << strength.bits_per_pixel()) - 1) as u8;
        let mut result = Vec::new();
        let mut current_byte = 0u8;
        let mut bit_count = 0;
        for &pixel in pixels.iter().take(data_len * 8) {
            let bit = pixel & mask & 1;
            current_byte = (current_byte << 1) | bit;
            bit_count += 1;
            if bit_count == 8 { result.push(current_byte); current_byte = 0; bit_count = 0; }
        }
        Ok(result)
    }
    pub fn verify(_original: &[u8], watermarked: &[u8], data: &[u8], strength: EmbedStrength) -> bool {
        let extracted = Self::extract(watermarked, data.len(), strength);
        match extracted { Ok(ext) => ext == data, Err(_) => false }
    }
}
#[cfg(test)] mod tests {
    use super::*;
    #[test] fn test_embed_extract() {
        let mut pixels = vec![128u8; 100];
        let data = b"TSM";
        WatermarkEncoder::embed(&mut pixels, data, EmbedStrength::Fragile).unwrap();
        let extracted = WatermarkEncoder::extract(&pixels, data.len(), EmbedStrength::Fragile).unwrap();
        assert_eq!(extracted, data);
    }
}
