//! Simple CRC bindings backed by miniz.c

use std::io;
use std::io::prelude::*;

use crc32fast::Hasher;

/// The CRC calculated by a [`CrcReader`].
///
/// [`CrcReader`]: struct.CrcReader.html
#[derive(Debug)]
pub struct Crc {
    amt: u32,
    hasher: Hasher,
}

/// A wrapper around a [`Read`] that calculates the CRC.
///
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
#[derive(Debug)]
pub struct CrcReader<R> {
    inner: R,
    crc: Crc,
}

impl Default for Crc {
    fn default() -> Self {
        Self::new()
    }
}

impl Crc {
    /// Create a new CRC.
    pub fn new() -> Crc {
        Crc {
            amt: 0,
            hasher: Hasher::new(),
        }
    }

    /// Returns the current crc32 checksum.
    pub fn sum(&self) -> u32 {
        self.hasher.clone().finalize()
    }

    /// The number of bytes that have been used to calculate the CRC.
    /// This value is only accurate if the amount is lower than 2<sup>32</sup>.
    pub fn amount(&self) -> u32 {
        self.amt
    }

    /// Update the CRC with the bytes in `data`.
    pub fn update(&mut self, data: &[u8]) {
        self.amt = self.amt.wrapping_add(data.len() as u32);
        self.hasher.update(data);
    }

    /// Reset the CRC.
    pub fn reset(&mut self) {
        self.amt = 0;
        self.hasher.reset();
    }

    /// Combine the CRC with the CRC for the subsequent block of bytes.
    pub fn combine(&mut self, additional_crc: &Crc) {
        self.amt = self.amt.wrapping_add(additional_crc.amt);
        self.hasher.combine(&additional_crc.hasher);
    }
}

impl<R: Read> CrcReader<R> {
    /// Create a new `CrcReader`.
    pub fn new(r: R) -> CrcReader<R> {
        CrcReader {
            inner: r,
            crc: Crc::new(),
        }
    }
}

impl<R> CrcReader<R> {
    /// Get the Crc for this `CrcReader`.
    pub fn crc(&self) -> &Crc {
        &self.crc
    }

    /// Get the reader that is wrapped by this `CrcReader`.
    pub fn into_inner(self) -> R {
        self.inner
    }

    /// Get the reader that is wrapped by this `CrcReader` by reference.
    pub fn get_ref(&self) -> &R {
        &self.inner
    }

    /// Get a mutable reference to the reader that is wrapped by this `CrcReader`.
    pub fn get_mut(&mut self) -> &mut R {
        &mut self.inner
    }

    /// Reset the Crc in this `CrcReader`.
    pub fn reset(&mut self) {
        self.crc.reset();
    }
}

impl<R: Read> Read for CrcReader<R> {
    fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
        let amt = self.inner.read(into)?;
        self.crc.update(&into[..amt]);
        Ok(amt)
    }
}

impl<R: BufRead> BufRead for CrcReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.inner.fill_buf()
    }
    fn consume(&mut self, amt: usize) {
        if let Ok(data) = self.inner.fill_buf() {
            self.crc.update(&data[..amt]);
        }
        self.inner.consume(amt);
    }
}

/// A wrapper around a [`Write`] that calculates the CRC.
///
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
#[derive(Debug)]
pub struct CrcWriter<W> {
    inner: W,
    crc: Crc,
}

impl<W> CrcWriter<W> {
    /// Get the Crc for this `CrcWriter`.
    pub fn crc(&self) -> &Crc {
        &self.crc
    }

    /// Get the writer that is wrapped by this `CrcWriter`.
    pub fn into_inner(self) -> W {
        self.inner
    }

    /// Get the writer that is wrapped by this `CrcWriter` by reference.
    pub fn get_ref(&self) -> &W {
        &self.inner
    }

    /// Get a mutable reference to the writer that is wrapped by this `CrcWriter`.
    pub fn get_mut(&mut self) -> &mut W {
        &mut self.inner
    }

    /// Reset the Crc in this `CrcWriter`.
    pub fn reset(&mut self) {
        self.crc.reset();
    }
}

impl<W: Write> CrcWriter<W> {
    /// Create a new `CrcWriter`.
    pub fn new(w: W) -> CrcWriter<W> {
        CrcWriter {
            inner: w,
            crc: Crc::new(),
        }
    }
}

impl<W: Write> Write for CrcWriter<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let amt = self.inner.write(buf)?;
        self.crc.update(&buf[..amt]);
        Ok(amt)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.inner.flush()
    }
}
