use crate::sm3::SM3;


pub struct HmacSm3 {
    inner_hash: SM3,
    outer_hash: SM3,
}


#[allow(dead_code)]
impl HmacSm3 {

    pub fn new(secret_key: &[u8]) -> Self {
        let mut k: Vec<u8> = vec![0u8; 64];
        if secret_key.len() <=64 {
            secret_key.iter().enumerate().for_each(|(i, x)| k[i] = *x );
        } else {
            let mut sm3 = SM3::new();
            sm3.update(secret_key);
            sm3.digest().iter().enumerate().for_each(|(i, x)| k[i] = *x );
        }

        let mut inner_hash = SM3::new();
        inner_hash.update(&k.iter().map(|x| x ^ 0x36).collect::<Vec<u8>>());
        let mut outer_hash = SM3::new();
        outer_hash.update(&k.iter().map(|x| x ^ 0x5C).collect::<Vec<u8>>());

        Self {
            inner_hash,
            outer_hash,
        }
    }

    pub fn update(&mut self, message: &[u8]) {
        self.inner_hash.update(message);
    }

    pub fn digest(mut self) -> Vec<u8> {
        self.outer_hash.update(&self.inner_hash.digest());
        self.outer_hash.digest()
    }
}
