use ring::digest;
use std::mem;
use crate::msgs::codec::Codec;
use crate::msgs::message::{Message, MessagePayload};
use crate::msgs::handshake::HandshakeMessagePayload;
#[cfg(feature = "logging")]
use crate::log::warn;

/// This deals with keeping a running hash of the handshake
/// payloads.  This is computed by buffering initially.  Once
/// we know what hash function we need to use we switch to
/// incremental hashing.
///
/// For client auth, we also need to buffer all the messages.
/// This is disabled in cases where client auth is not possible.
pub struct HandshakeHash {
    /// None before we know what hash function we're using
    alg: Option<&'static digest::Algorithm>,

    /// None before we know what hash function we're using
    ctx: Option<digest::Context>,

    /// true if we need to keep all messages
    client_auth_enabled: bool,

    /// buffer for pre-hashing stage and client-auth.
    buffer: Vec<u8>,
}

impl HandshakeHash {
    pub fn new() -> HandshakeHash {
        HandshakeHash {
            alg: None,
            ctx: None,
            client_auth_enabled: false,
            buffer: Vec::new(),
        }
    }

    /// We might be doing client auth, so need to keep a full
    /// log of the handshake.
    pub fn set_client_auth_enabled(&mut self) {
        debug_assert!(self.ctx.is_none()); // or we might have already discarded messages
        self.client_auth_enabled = true;
    }

    /// We decided not to do client auth after all, so discard
    /// the transcript.
    pub fn abandon_client_auth(&mut self) {
        self.client_auth_enabled = false;
        self.buffer.drain(..);
    }

    /// We now know what hash function the verify_data will use.
    pub fn start_hash(&mut self, alg: &'static digest::Algorithm) -> bool {
        match self.alg {
            None => {},
            Some(started) => {
                if started != alg {
                    // hash type is changing
                    warn!("altered hash to HandshakeHash::start_hash");
                    return false;
                }

                return true;
            }
        }
        self.alg = Some(alg);
        debug_assert!(self.ctx.is_none());

        let mut ctx = digest::Context::new(alg);
        ctx.update(&self.buffer);
        self.ctx = Some(ctx);

        // Discard buffer if we don't need it now.
        if !self.client_auth_enabled {
            self.buffer.drain(..);
        }
        true
    }

    /// Hash/buffer a handshake message.
    pub fn add_message(&mut self, m: &Message) -> &mut HandshakeHash {
        match m.payload {
            MessagePayload::Handshake(ref hs) => {
                let buf = hs.get_encoding();
                self.update_raw(&buf);
            }
            _ => unreachable!(),
        };
        self
    }

    /// Hash or buffer a byte slice.
    fn update_raw(&mut self, buf: &[u8]) -> &mut Self {
        if self.ctx.is_some() {
            self.ctx.as_mut().unwrap().update(buf);
        }

        if self.ctx.is_none() || self.client_auth_enabled {
            self.buffer.extend_from_slice(buf);
        }

        self
    }

    /// Get the hash value if we were to hash `extra` too,
    /// using hash function `hash`.
    pub fn get_hash_given(&self, hash: &'static digest::Algorithm, extra: &[u8]) -> Vec<u8> {
        let mut ctx = if self.ctx.is_none() {
            let mut ctx = digest::Context::new(hash);
            ctx.update(&self.buffer);
            ctx
        } else {
            self.ctx.as_ref().unwrap().clone()
        };

        ctx.update(extra);
        let hash = ctx.finish();
        let mut ret = Vec::new();
        ret.extend_from_slice(hash.as_ref());
        ret
    }

    /// Take the current hash value, and encapsulate it in a
    /// 'handshake_hash' handshake message.  Start this hash
    /// again, with that message at the front.
    pub fn rollup_for_hrr(&mut self) {
        let old_hash = self.ctx.take().unwrap().finish();
        let old_handshake_hash_msg = HandshakeMessagePayload::build_handshake_hash(old_hash.as_ref());

        self.ctx = Some(digest::Context::new(self.alg.unwrap()));
        self.update_raw(&old_handshake_hash_msg.get_encoding());
    }

    /// Get the current hash value.
    pub fn get_current_hash(&self) -> Vec<u8> {
        let hash = self.ctx.as_ref().unwrap().clone().finish();
        let mut ret = Vec::new();
        ret.extend_from_slice(hash.as_ref());
        ret
    }

    /// Takes this object's buffer containing all handshake messages
    /// so far.  This method only works once; it resets the buffer
    /// to empty.
    pub fn take_handshake_buf(&mut self) -> Vec<u8> {
        debug_assert!(self.client_auth_enabled);
        mem::replace(&mut self.buffer, Vec::new())
    }
}

#[cfg(test)]
mod test {
    use super::HandshakeHash;
    use ring::digest;

    #[test]
    fn hashes_correctly() {
        let mut hh = HandshakeHash::new();
        hh.update_raw(b"hello");
        assert_eq!(hh.buffer.len(), 5);
        hh.start_hash(&digest::SHA256);
        assert_eq!(hh.buffer.len(), 0);
        hh.update_raw(b"world");
        let h = hh.get_current_hash();
        assert_eq!(h[0], 0x93);
        assert_eq!(h[1], 0x6a);
        assert_eq!(h[2], 0x18);
        assert_eq!(h[3], 0x5c);
    }

    #[test]
    fn buffers_correctly() {
        let mut hh = HandshakeHash::new();
        hh.set_client_auth_enabled();
        hh.update_raw(b"hello");
        assert_eq!(hh.buffer.len(), 5);
        hh.start_hash(&digest::SHA256);
        assert_eq!(hh.buffer.len(), 5);
        hh.update_raw(b"world");
        assert_eq!(hh.buffer.len(), 10);
        let h = hh.get_current_hash();
        assert_eq!(h[0], 0x93);
        assert_eq!(h[1], 0x6a);
        assert_eq!(h[2], 0x18);
        assert_eq!(h[3], 0x5c);
        let buf = hh.take_handshake_buf();
        assert_eq!(b"helloworld".to_vec(), buf);
    }

    #[test]
    fn abandon() {
        let mut hh = HandshakeHash::new();
        hh.set_client_auth_enabled();
        hh.update_raw(b"hello");
        assert_eq!(hh.buffer.len(), 5);
        hh.start_hash(&digest::SHA256);
        assert_eq!(hh.buffer.len(), 5);
        hh.abandon_client_auth();
        assert_eq!(hh.buffer.len(), 0);
        hh.update_raw(b"world");
        assert_eq!(hh.buffer.len(), 0);
        let h = hh.get_current_hash();
        assert_eq!(h[0], 0x93);
        assert_eq!(h[1], 0x6a);
        assert_eq!(h[2], 0x18);
        assert_eq!(h[3], 0x5c);
    }
}
