#![doc(hidden)]

//! `CodedInputStream` and `CodedOutputStream` implementations

use std::io;
use std::io::BufRead;
use std::io::Read;
use std::mem;
use std::slice;

#[cfg(feature = "bytes")]
use crate::chars::Chars;
#[cfg(feature = "bytes")]
use bytes::Bytes;

use crate::buf_read_iter::BufReadIter;
use crate::enums::ProtobufEnum;
use crate::error::ProtobufError;
use crate::error::ProtobufResult;
use crate::error::WireError;
use crate::message::Message;
use crate::unknown::UnknownValue;
use crate::wire_format;
use crate::zigzag::decode_zig_zag_32;
use crate::zigzag::decode_zig_zag_64;

/// Default recursion level limit. 100 is the default value of C++'s implementation.
const DEFAULT_RECURSION_LIMIT: u32 = 100;

/// Max allocated vec when reading length-delimited from unknown input stream
pub(crate) const READ_RAW_BYTES_MAX_ALLOC: usize = 10_000_000;

/// Buffered read with handy utilities.
pub struct CodedInputStream<'a> {
    source: BufReadIter<'a>,
    recursion_level: u32,
    recursion_limit: u32,
}

impl<'a> CodedInputStream<'a> {
    /// Wrap a `Read`.
    ///
    /// Note resulting `CodedInputStream` is buffered even if `Read` is not.
    pub fn new(read: &'a mut dyn Read) -> CodedInputStream<'a> {
        CodedInputStream::from_buf_read_iter(BufReadIter::from_read(read))
    }

    /// Create from `BufRead`.
    ///
    /// `CodedInputStream` will utilize `BufRead` buffer.
    pub fn from_buffered_reader(buf_read: &'a mut dyn BufRead) -> CodedInputStream<'a> {
        CodedInputStream::from_buf_read_iter(BufReadIter::from_buf_read(buf_read))
    }

    /// Read from byte slice
    pub fn from_bytes(bytes: &'a [u8]) -> CodedInputStream<'a> {
        CodedInputStream::from_buf_read_iter(BufReadIter::from_byte_slice(bytes))
    }

    /// Read from `Bytes`.
    ///
    /// `CodedInputStream` operations like
    /// [`read_carllerche_bytes`](crate::CodedInputStream::read_carllerche_bytes)
    /// will return a shared copy of this bytes object.
    #[cfg(feature = "bytes")]
    pub fn from_carllerche_bytes(bytes: &'a Bytes) -> CodedInputStream<'a> {
        CodedInputStream::from_buf_read_iter(BufReadIter::from_bytes(bytes))
    }

    fn from_buf_read_iter(source: BufReadIter<'a>) -> CodedInputStream<'a> {
        CodedInputStream {
            source: source,
            recursion_level: 0,
            recursion_limit: DEFAULT_RECURSION_LIMIT,
        }
    }

    /// Set the recursion limit.
    pub fn set_recursion_limit(&mut self, limit: u32) {
        self.recursion_limit = limit;
    }

    #[inline]
    pub(crate) fn incr_recursion(&mut self) -> ProtobufResult<()> {
        if self.recursion_level >= self.recursion_limit {
            return Err(ProtobufError::WireError(WireError::OverRecursionLimit));
        }
        self.recursion_level += 1;
        Ok(())
    }

    #[inline]
    pub(crate) fn decr_recursion(&mut self) {
        self.recursion_level -= 1;
    }

    /// How many bytes processed
    pub fn pos(&self) -> u64 {
        self.source.pos()
    }

    /// How many bytes until current limit
    pub fn bytes_until_limit(&self) -> u64 {
        self.source.bytes_until_limit()
    }

    /// Read bytes into given `buf`.
    ///
    /// Return `0` on EOF.
    // TODO: overload with `Read::read`
    pub fn read(&mut self, buf: &mut [u8]) -> ProtobufResult<()> {
        self.source.read_exact(buf)?;
        Ok(())
    }

    /// Read exact number of bytes as `Bytes` object.
    ///
    /// This operation returns a shared view if `CodedInputStream` is
    /// constructed with `Bytes` parameter.
    #[cfg(feature = "bytes")]
    fn read_raw_callerche_bytes(&mut self, count: usize) -> ProtobufResult<Bytes> {
        self.source.read_exact_bytes(count)
    }

    /// Read one byte
    #[inline(always)]
    pub fn read_raw_byte(&mut self) -> ProtobufResult<u8> {
        self.source.read_byte()
    }

    /// Push new limit, return previous limit.
    pub fn push_limit(&mut self, limit: u64) -> ProtobufResult<u64> {
        self.source.push_limit(limit)
    }

    /// Restore previous limit.
    pub fn pop_limit(&mut self, old_limit: u64) {
        self.source.pop_limit(old_limit);
    }

    /// Are we at EOF?
    #[inline(always)]
    pub fn eof(&mut self) -> ProtobufResult<bool> {
        self.source.eof()
    }

    /// Check we are at EOF.
    ///
    /// Return error if we are not at EOF.
    pub fn check_eof(&mut self) -> ProtobufResult<()> {
        let eof = self.eof()?;
        if !eof {
            return Err(ProtobufError::WireError(WireError::UnexpectedEof));
        }
        Ok(())
    }

    fn read_raw_varint64_slow(&mut self) -> ProtobufResult<u64> {
        let mut r: u64 = 0;
        let mut i = 0;
        loop {
            if i == 10 {
                return Err(ProtobufError::WireError(WireError::IncorrectVarint));
            }
            let b = self.read_raw_byte()?;
            // TODO: may overflow if i == 9
            r = r | (((b & 0x7f) as u64) << (i * 7));
            i += 1;
            if b < 0x80 {
                return Ok(r);
            }
        }
    }

    /// Read varint
    #[inline(always)]
    pub fn read_raw_varint64(&mut self) -> ProtobufResult<u64> {
        'slow: loop {
            let ret;
            let consume;

            loop {
                let rem = self.source.remaining_in_buf();

                if rem.len() >= 1 {
                    // most varints are in practice fit in 1 byte
                    if rem[0] < 0x80 {
                        ret = rem[0] as u64;
                        consume = 1;
                    } else {
                        // handle case of two bytes too
                        if rem.len() >= 2 && rem[1] < 0x80 {
                            ret = (rem[0] & 0x7f) as u64 | (rem[1] as u64) << 7;
                            consume = 2;
                        } else if rem.len() >= 10 {
                            // Read from array when buf at at least 10 bytes,
                            // max len for varint.
                            let mut r: u64 = 0;
                            let mut i: usize = 0;
                            {
                                let rem = rem;
                                loop {
                                    if i == 10 {
                                        return Err(ProtobufError::WireError(
                                            WireError::IncorrectVarint,
                                        ));
                                    }

                                    let b = if true {
                                        // skip range check
                                        unsafe { *rem.get_unchecked(i) }
                                    } else {
                                        rem[i]
                                    };

                                    // TODO: may overflow if i == 9
                                    r = r | (((b & 0x7f) as u64) << (i * 7));
                                    i += 1;
                                    if b < 0x80 {
                                        break;
                                    }
                                }
                            }
                            consume = i;
                            ret = r;
                        } else {
                            break 'slow;
                        }
                    }
                } else {
                    break 'slow;
                }
                break;
            }

            self.source.consume(consume);
            return Ok(ret);
        }

        self.read_raw_varint64_slow()
    }

    /// Read varint
    #[inline(always)]
    pub fn read_raw_varint32(&mut self) -> ProtobufResult<u32> {
        self.read_raw_varint64().map(|v| v as u32)
    }

    /// Read little-endian 32-bit integer
    pub fn read_raw_little_endian32(&mut self) -> ProtobufResult<u32> {
        let mut r = 0u32;
        let bytes: &mut [u8] = unsafe {
            let p: *mut u8 = mem::transmute(&mut r);
            slice::from_raw_parts_mut(p, mem::size_of::<u32>())
        };
        self.read(bytes)?;
        Ok(r.to_le())
    }

    /// Read little-endian 64-bit integer
    pub fn read_raw_little_endian64(&mut self) -> ProtobufResult<u64> {
        let mut r = 0u64;
        let bytes: &mut [u8] = unsafe {
            let p: *mut u8 = mem::transmute(&mut r);
            slice::from_raw_parts_mut(p, mem::size_of::<u64>())
        };
        self.read(bytes)?;
        Ok(r.to_le())
    }

    /// Read tag
    #[inline]
    pub fn read_tag(&mut self) -> ProtobufResult<wire_format::Tag> {
        let v = self.read_raw_varint32()?;
        match wire_format::Tag::new(v) {
            Some(tag) => Ok(tag),
            None => Err(ProtobufError::WireError(WireError::IncorrectTag(v))),
        }
    }

    /// Read tag, return it is pair (field number, wire type)
    #[inline]
    pub fn read_tag_unpack(&mut self) -> ProtobufResult<(u32, wire_format::WireType)> {
        self.read_tag().map(|t| t.unpack())
    }

    /// Read `double`
    pub fn read_double(&mut self) -> ProtobufResult<f64> {
        let bits = self.read_raw_little_endian64()?;
        unsafe { Ok(mem::transmute::<u64, f64>(bits)) }
    }

    /// Read `float`
    pub fn read_float(&mut self) -> ProtobufResult<f32> {
        let bits = self.read_raw_little_endian32()?;
        unsafe { Ok(mem::transmute::<u32, f32>(bits)) }
    }

    /// Read `int64`
    pub fn read_int64(&mut self) -> ProtobufResult<i64> {
        self.read_raw_varint64().map(|v| v as i64)
    }

    /// Read `int32`
    pub fn read_int32(&mut self) -> ProtobufResult<i32> {
        self.read_raw_varint32().map(|v| v as i32)
    }

    /// Read `uint64`
    pub fn read_uint64(&mut self) -> ProtobufResult<u64> {
        self.read_raw_varint64()
    }

    /// Read `uint32`
    pub fn read_uint32(&mut self) -> ProtobufResult<u32> {
        self.read_raw_varint32()
    }

    /// Read `sint64`
    pub fn read_sint64(&mut self) -> ProtobufResult<i64> {
        self.read_uint64().map(decode_zig_zag_64)
    }

    /// Read `sint32`
    pub fn read_sint32(&mut self) -> ProtobufResult<i32> {
        self.read_uint32().map(decode_zig_zag_32)
    }

    /// Read `fixed64`
    pub fn read_fixed64(&mut self) -> ProtobufResult<u64> {
        self.read_raw_little_endian64()
    }

    /// Read `fixed32`
    pub fn read_fixed32(&mut self) -> ProtobufResult<u32> {
        self.read_raw_little_endian32()
    }

    /// Read `sfixed64`
    pub fn read_sfixed64(&mut self) -> ProtobufResult<i64> {
        self.read_raw_little_endian64().map(|v| v as i64)
    }

    /// Read `sfixed32`
    pub fn read_sfixed32(&mut self) -> ProtobufResult<i32> {
        self.read_raw_little_endian32().map(|v| v as i32)
    }

    /// Read `bool`
    pub fn read_bool(&mut self) -> ProtobufResult<bool> {
        self.read_raw_varint32().map(|v| v != 0)
    }

    /// Read `enum` as `ProtobufEnum`
    pub fn read_enum<E: ProtobufEnum>(&mut self) -> ProtobufResult<E> {
        let i = self.read_int32()?;
        match ProtobufEnum::from_i32(i) {
            Some(e) => Ok(e),
            None => Err(ProtobufError::WireError(WireError::InvalidEnumValue(i))),
        }
    }

    /// Read `repeated` packed `double`
    pub fn read_repeated_packed_double_into(
        &mut self,
        target: &mut Vec<f64>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 4) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_double()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read `repeated` packed `float`
    pub fn read_repeated_packed_float_into(&mut self, target: &mut Vec<f32>) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 4) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_float()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read `repeated` packed `int64`
    pub fn read_repeated_packed_int64_into(&mut self, target: &mut Vec<i64>) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len as u64)?;
        while !self.eof()? {
            target.push(self.read_int64()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `int32`
    pub fn read_repeated_packed_int32_into(&mut self, target: &mut Vec<i32>) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_int32()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `uint64`
    pub fn read_repeated_packed_uint64_into(
        &mut self,
        target: &mut Vec<u64>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_uint64()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `uint32`
    pub fn read_repeated_packed_uint32_into(
        &mut self,
        target: &mut Vec<u32>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_uint32()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `sint64`
    pub fn read_repeated_packed_sint64_into(
        &mut self,
        target: &mut Vec<i64>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_sint64()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `sint32`
    pub fn read_repeated_packed_sint32_into(
        &mut self,
        target: &mut Vec<i32>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_sint32()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `fixed64`
    pub fn read_repeated_packed_fixed64_into(
        &mut self,
        target: &mut Vec<u64>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 8) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_fixed64()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `fixed32`
    pub fn read_repeated_packed_fixed32_into(
        &mut self,
        target: &mut Vec<u32>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 4) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_fixed32()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `sfixed64`
    pub fn read_repeated_packed_sfixed64_into(
        &mut self,
        target: &mut Vec<i64>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 8) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_sfixed64()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `sfixed32`
    pub fn read_repeated_packed_sfixed32_into(
        &mut self,
        target: &mut Vec<i32>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        target.reserve((len / 4) as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_sfixed32()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `bool`
    pub fn read_repeated_packed_bool_into(&mut self, target: &mut Vec<bool>) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;

        // regular bool value is 1-byte size
        target.reserve(len as usize);

        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_bool()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read repeated packed `enum` into `ProtobufEnum`
    pub fn read_repeated_packed_enum_into<E: ProtobufEnum>(
        &mut self,
        target: &mut Vec<E>,
    ) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        while !self.eof()? {
            target.push(self.read_enum()?);
        }
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read `UnknownValue`
    pub fn read_unknown(
        &mut self,
        wire_type: wire_format::WireType,
    ) -> ProtobufResult<UnknownValue> {
        match wire_type {
            wire_format::WireTypeVarint => {
                self.read_raw_varint64().map(|v| UnknownValue::Varint(v))
            }
            wire_format::WireTypeFixed64 => self.read_fixed64().map(|v| UnknownValue::Fixed64(v)),
            wire_format::WireTypeFixed32 => self.read_fixed32().map(|v| UnknownValue::Fixed32(v)),
            wire_format::WireTypeLengthDelimited => {
                let len = self.read_raw_varint32()?;
                self.read_raw_bytes(len)
                    .map(|v| UnknownValue::LengthDelimited(v))
            }
            _ => Err(ProtobufError::WireError(WireError::UnexpectedWireType(
                wire_type,
            ))),
        }
    }

    /// Skip field
    pub fn skip_field(&mut self, wire_type: wire_format::WireType) -> ProtobufResult<()> {
        self.read_unknown(wire_type).map(|_| ())
    }

    /// Read raw bytes into the supplied vector.  The vector will be resized as needed and
    /// overwritten.
    pub fn read_raw_bytes_into(&mut self, count: u32, target: &mut Vec<u8>) -> ProtobufResult<()> {
        if false {
            // Master uses this version, but keep existing version for a while
            // to avoid possible breakages.
            return self.source.read_exact_to_vec(count as usize, target);
        }

        let count = count as usize;

        // TODO: also do some limits when reading from unlimited source
        if count as u64 > self.source.bytes_until_limit() {
            return Err(ProtobufError::WireError(WireError::TruncatedMessage));
        }

        unsafe {
            target.set_len(0);
        }

        if count >= READ_RAW_BYTES_MAX_ALLOC {
            // avoid calling `reserve` on buf with very large buffer: could be a malformed message

            let mut take = self.by_ref().take(count as u64);
            take.read_to_end(target)?;

            if target.len() != count {
                return Err(ProtobufError::WireError(WireError::TruncatedMessage));
            }
        } else {
            target.reserve(count);
            unsafe {
                target.set_len(count);
            }

            self.source.read_exact(target)?;
        }
        Ok(())
    }

    /// Read exact number of bytes
    pub fn read_raw_bytes(&mut self, count: u32) -> ProtobufResult<Vec<u8>> {
        let mut r = Vec::new();
        self.read_raw_bytes_into(count, &mut r)?;
        Ok(r)
    }

    /// Skip exact number of bytes
    pub fn skip_raw_bytes(&mut self, count: u32) -> ProtobufResult<()> {
        // TODO: make it more efficient
        self.read_raw_bytes(count).map(|_| ())
    }

    /// Read `bytes` field, length delimited
    pub fn read_bytes(&mut self) -> ProtobufResult<Vec<u8>> {
        let mut r = Vec::new();
        self.read_bytes_into(&mut r)?;
        Ok(r)
    }

    /// Read `bytes` field, length delimited
    #[cfg(feature = "bytes")]
    pub fn read_carllerche_bytes(&mut self) -> ProtobufResult<Bytes> {
        let len = self.read_raw_varint32()?;
        self.read_raw_callerche_bytes(len as usize)
    }

    /// Read `string` field, length delimited
    #[cfg(feature = "bytes")]
    pub fn read_carllerche_chars(&mut self) -> ProtobufResult<Chars> {
        let bytes = self.read_carllerche_bytes()?;
        Ok(Chars::from_bytes(bytes)?)
    }

    /// Read `bytes` field, length delimited
    pub fn read_bytes_into(&mut self, target: &mut Vec<u8>) -> ProtobufResult<()> {
        let len = self.read_raw_varint32()?;
        self.read_raw_bytes_into(len, target)?;
        Ok(())
    }

    /// Read `string` field, length delimited
    pub fn read_string(&mut self) -> ProtobufResult<String> {
        let mut r = String::new();
        self.read_string_into(&mut r)?;
        Ok(r)
    }

    /// Read `string` field, length delimited
    pub fn read_string_into(&mut self, target: &mut String) -> ProtobufResult<()> {
        target.clear();
        // take target's buffer
        let mut vec = mem::replace(target, String::new()).into_bytes();
        self.read_bytes_into(&mut vec)?;

        let s = match String::from_utf8(vec) {
            Ok(t) => t,
            Err(_) => return Err(ProtobufError::WireError(WireError::Utf8Error)),
        };
        *target = s;
        Ok(())
    }

    /// Read message, do not check if message is initialized
    pub fn merge_message<M: Message>(&mut self, message: &mut M) -> ProtobufResult<()> {
        let len = self.read_raw_varint64()?;
        let old_limit = self.push_limit(len)?;
        message.merge_from(self)?;
        self.pop_limit(old_limit);
        Ok(())
    }

    /// Read message
    pub fn read_message<M: Message>(&mut self) -> ProtobufResult<M> {
        let mut r: M = Message::new();
        self.merge_message(&mut r)?;
        r.check_initialized()?;
        Ok(r)
    }
}

impl<'a> Read for CodedInputStream<'a> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.source.read(buf).map_err(Into::into)
    }
}

impl<'a> BufRead for CodedInputStream<'a> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf().map_err(Into::into)
    }

    fn consume(&mut self, amt: usize) {
        self.source.consume(amt)
    }
}

/// Helper internal utility, should not be used directly
#[doc(hidden)]
pub trait WithCodedInputStream {
    fn with_coded_input_stream<T, F>(self, cb: F) -> ProtobufResult<T>
    where
        F: FnOnce(&mut CodedInputStream) -> ProtobufResult<T>;
}

impl<'a> WithCodedInputStream for &'a mut (dyn Read + 'a) {
    fn with_coded_input_stream<T, F>(self, cb: F) -> ProtobufResult<T>
    where
        F: FnOnce(&mut CodedInputStream) -> ProtobufResult<T>,
    {
        let mut is = CodedInputStream::new(self);
        let r = cb(&mut is)?;
        is.check_eof()?;
        Ok(r)
    }
}

impl<'a> WithCodedInputStream for &'a mut (dyn BufRead + 'a) {
    fn with_coded_input_stream<T, F>(self, cb: F) -> ProtobufResult<T>
    where
        F: FnOnce(&mut CodedInputStream) -> ProtobufResult<T>,
    {
        let mut is = CodedInputStream::from_buffered_reader(self);
        let r = cb(&mut is)?;
        is.check_eof()?;
        Ok(r)
    }
}

impl<'a> WithCodedInputStream for &'a [u8] {
    fn with_coded_input_stream<T, F>(self, cb: F) -> ProtobufResult<T>
    where
        F: FnOnce(&mut CodedInputStream) -> ProtobufResult<T>,
    {
        let mut is = CodedInputStream::from_bytes(self);
        let r = cb(&mut is)?;
        is.check_eof()?;
        Ok(r)
    }
}

#[cfg(feature = "bytes")]
impl<'a> WithCodedInputStream for &'a Bytes {
    fn with_coded_input_stream<T, F>(self, cb: F) -> ProtobufResult<T>
    where
        F: FnOnce(&mut CodedInputStream) -> ProtobufResult<T>,
    {
        let mut is = CodedInputStream::from_carllerche_bytes(self);
        let r = cb(&mut is)?;
        is.check_eof()?;
        Ok(r)
    }
}

#[cfg(test)]
mod test {

    use std::fmt::Debug;
    use std::io;
    use std::io::BufRead;
    use std::io::Read;

    use crate::error::ProtobufError;
    use crate::error::ProtobufResult;
    use crate::hex::decode_hex;

    use super::CodedInputStream;
    use super::READ_RAW_BYTES_MAX_ALLOC;

    fn test_read_partial<F>(hex: &str, mut callback: F)
    where
        F: FnMut(&mut CodedInputStream),
    {
        let d = decode_hex(hex);
        let mut reader = io::Cursor::new(d);
        let mut is = CodedInputStream::from_buffered_reader(&mut reader as &mut dyn BufRead);
        assert_eq!(0, is.pos());
        callback(&mut is);
    }

    fn test_read<F>(hex: &str, mut callback: F)
    where
        F: FnMut(&mut CodedInputStream),
    {
        let len = decode_hex(hex).len();
        test_read_partial(hex, |reader| {
            callback(reader);
            assert!(reader.eof().expect("eof"));
            assert_eq!(len as u64, reader.pos());
        });
    }

    fn test_read_v<F, V>(hex: &str, v: V, mut callback: F)
    where
        F: FnMut(&mut CodedInputStream) -> ProtobufResult<V>,
        V: PartialEq + Debug,
    {
        test_read(hex, |reader| {
            assert_eq!(v, callback(reader).unwrap());
        });
    }

    #[test]
    fn test_input_stream_read_raw_byte() {
        test_read("17", |is| {
            assert_eq!(23, is.read_raw_byte().unwrap());
        });
    }

    #[test]
    fn test_input_stream_read_raw_varint() {
        test_read_v("07", 7, |reader| reader.read_raw_varint32());
        test_read_v("07", 7, |reader| reader.read_raw_varint64());

        test_read_v("96 01", 150, |reader| reader.read_raw_varint32());
        test_read_v("96 01", 150, |reader| reader.read_raw_varint64());

        test_read_v(
            "ff ff ff ff ff ff ff ff ff 01",
            0xffffffffffffffff,
            |reader| reader.read_raw_varint64(),
        );

        test_read_v("ff ff ff ff 0f", 0xffffffff, |reader| {
            reader.read_raw_varint32()
        });
        test_read_v("ff ff ff ff 0f", 0xffffffff, |reader| {
            reader.read_raw_varint64()
        });
    }

    #[test]
    fn test_input_stream_read_raw_vaint_malformed() {
        // varint cannot have length > 10
        test_read_partial("ff ff ff ff ff ff ff ff ff ff 01", |reader| {
            let result = reader.read_raw_varint64();
            match result {
                // TODO: make an enum variant
                Err(ProtobufError::WireError(..)) => (),
                _ => panic!(),
            }
        });
        test_read_partial("ff ff ff ff ff ff ff ff ff ff 01", |reader| {
            let result = reader.read_raw_varint32();
            match result {
                // TODO: make an enum variant
                Err(ProtobufError::WireError(..)) => (),
                _ => panic!(),
            }
        });
    }

    #[test]
    fn test_input_stream_read_raw_varint_unexpected_eof() {
        test_read_partial("96 97", |reader| {
            let result = reader.read_raw_varint32();
            match result {
                Err(ProtobufError::WireError(..)) => (),
                _ => panic!(),
            }
        });
    }

    #[test]
    fn test_input_stream_read_raw_varint_pos() {
        test_read_partial("95 01 98", |reader| {
            assert_eq!(149, reader.read_raw_varint32().unwrap());
            assert_eq!(2, reader.pos());
        });
    }

    #[test]
    fn test_input_stream_read_int32() {
        test_read_v("02", 2, |reader| reader.read_int32());
    }

    #[test]
    fn test_input_stream_read_float() {
        test_read_v("95 73 13 61", 17e19, |is| is.read_float());
    }

    #[test]
    fn test_input_stream_read_double() {
        test_read_v("40 d5 ab 68 b3 07 3d 46", 23e29, |is| is.read_double());
    }

    #[test]
    fn test_input_stream_skip_raw_bytes() {
        test_read("", |reader| {
            reader.skip_raw_bytes(0).unwrap();
        });
        test_read("aa bb", |reader| {
            reader.skip_raw_bytes(2).unwrap();
        });
        test_read("aa bb cc dd ee ff", |reader| {
            reader.skip_raw_bytes(6).unwrap();
        });
    }

    #[test]
    fn test_input_stream_read_raw_bytes() {
        test_read("", |reader| {
            assert_eq!(
                Vec::from(&b""[..]),
                reader.read_raw_bytes(0).expect("read_raw_bytes")
            );
        })
    }

    #[test]
    fn test_input_stream_limits() {
        test_read("aa bb cc", |is| {
            let old_limit = is.push_limit(1).unwrap();
            assert_eq!(1, is.bytes_until_limit());
            let r1 = is.read_raw_bytes(1).unwrap();
            assert_eq!(&[0xaa as u8], &r1[..]);
            is.pop_limit(old_limit);
            let r2 = is.read_raw_bytes(2).unwrap();
            assert_eq!(&[0xbb as u8, 0xcc], &r2[..]);
        });
    }

    #[test]
    fn test_input_stream_io_read() {
        test_read("aa bb cc", |is| {
            let mut buf = [0; 3];
            assert_eq!(Read::read(is, &mut buf).expect("io::Read"), 3);
            assert_eq!(buf, [0xaa, 0xbb, 0xcc]);
        });
    }

    #[test]
    fn test_input_stream_io_bufread() {
        test_read("aa bb cc", |is| {
            assert_eq!(
                BufRead::fill_buf(is).expect("io::BufRead::fill_buf"),
                &[0xaa, 0xbb, 0xcc]
            );
            BufRead::consume(is, 3);
        });
    }

    #[test]
    fn test_input_stream_read_raw_bytes_into_huge() {
        let mut v = Vec::new();
        for i in 0..READ_RAW_BYTES_MAX_ALLOC + 1000 {
            v.push((i % 10) as u8);
        }

        let mut slice: &[u8] = v.as_slice();

        let mut is = CodedInputStream::new(&mut slice);

        let mut buf = Vec::new();

        is.read_raw_bytes_into(READ_RAW_BYTES_MAX_ALLOC as u32 + 10, &mut buf)
            .expect("read");

        assert_eq!(READ_RAW_BYTES_MAX_ALLOC + 10, buf.len());

        buf.clear();

        is.read_raw_bytes_into(1000 - 10, &mut buf).expect("read");

        assert_eq!(1000 - 10, buf.len());

        assert!(is.eof().expect("eof"));
    }
}
