use crate::zerokms::IndexKey;
use zeroize::{Zeroize, ZeroizeOnDrop};

use super::mac::Macca;

#[derive(Zeroize, ZeroizeOnDrop)]
pub(super) struct Blake3PrefixMac {
    prefix: Vec<u8>,
    hasher: blake3::Hasher,
}

impl Blake3PrefixMac {
    pub fn new(key: &IndexKey, prefix: Vec<u8>) -> Self {
        let mut hasher = blake3::Hasher::new_keyed(key.key());
        hasher.update(&prefix);

        Self { prefix, hasher }
    }

    fn reset(&mut self) {
        self.hasher.reset();
        self.hasher.update(&self.prefix);
    }
}

impl Macca for Blake3PrefixMac {
    fn update(&mut self, bytes: &[u8]) {
        self.hasher.update(bytes);
    }

    fn finalize_reset<const N: usize>(&mut self) -> [u8; N] {
        let mut output = [0; N];
        self.hasher.finalize_xof().fill(&mut output);
        self.reset();
        output
    }
}
