// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Functionality for deserializing CBOR data into values.

use alloc::{str, vec::Vec};

use super::values::{Constants, SimpleValue, Value};
use crate::{
    cbor_array_vec, cbor_bytes_lit, cbor_map_collection, cbor_tagged, cbor_text, cbor_unsigned,
};

/// Possible errors from a deserialization operation.
#[derive(Debug, PartialEq)]
pub enum DecoderError {
    UnsupportedMajorType,
    UnknownAdditionalInfo,
    IncompleteCborData,
    TooMuchNesting,
    InvalidUtf8,
    ExtraneousData,
    OutOfOrderKey,
    NonMinimalCborEncoding,
    UnsupportedSimpleValue,
    UnsupportedFloatingPointValue,
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.
/// Maximum level of nesting supported is 127; more deeply nested structures will fail with
/// [`DecoderError::TooMuchNesting`].
pub fn read(encoded_cbor: &[u8]) -> Result<Value, DecoderError> {
    read_nested(encoded_cbor, Some(i8::MAX))
}

/// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data.  If
/// `max_nest` is `Some(max)`, then nested structures are only supported up to the given limit (returning
/// [`DecoderError::TooMuchNesting`] if the limit is hit).
pub fn read_nested(encoded_cbor: &[u8], max_nest: Option<i8>) -> Result<Value, DecoderError> {
    let mut reader = Reader::new(encoded_cbor);
    let value = reader.decode_complete_data_item(max_nest)?;
    if !reader.remaining_cbor.is_empty() {
        return Err(DecoderError::ExtraneousData);
    }
    Ok(value)
}

/// Deserialize CBOR binary data to produce a single [`Value`].  If `max_nest` is `Some(max)`, then
/// nested structures are only supported up to the given limit (returning
/// [`DecoderError::TooMuchNesting`] if the limit is hit).
pub fn read_nested_non_strict(
    encoded_cbor: &[u8],
    max_nest: Option<i8>,
) -> Result<Value, DecoderError> {
    let mut reader = Reader::new_non_strict(encoded_cbor);
    let value = reader.decode_complete_data_item(max_nest)?;
    Ok(value)
}

struct Reader<'a> {
    non_strict: bool,
    remaining_cbor: &'a [u8],
}

impl<'a> Reader<'a> {
    pub fn new(cbor: &'a [u8]) -> Reader<'a> {
        Reader {
            non_strict: false,
            remaining_cbor: cbor,
        }
    }

    pub fn new_non_strict(cbor: &'a [u8]) -> Reader<'a> {
        Reader {
            non_strict: true,
            remaining_cbor: cbor,
        }
    }

    pub fn decode_complete_data_item(
        &mut self,
        remaining_depth: Option<i8>,
    ) -> Result<Value, DecoderError> {
        if remaining_depth.map_or(false, |d| d < 0) {
            return Err(DecoderError::TooMuchNesting);
        }

        match self.read_bytes(1) {
            Some([first_byte]) => {
                // Unsigned byte means logical shift, so only zeros get shifted in.
                let major_type_value = first_byte >> Constants::MAJOR_TYPE_BIT_SHIFT;
                let additional_info = first_byte & Constants::ADDITIONAL_INFORMATION_MASK;
                let size_value = self.read_variadic_length_integer(additional_info)?;
                match major_type_value {
                    0 => self.decode_value_to_unsigned(size_value),
                    1 => self.decode_value_to_negative(size_value),
                    2 => self.read_byte_string_content(size_value),
                    3 => self.read_text_string_content(size_value),
                    4 => self.read_array_content(size_value, remaining_depth),
                    5 => self.read_map_content(size_value, remaining_depth),
                    6 => self.read_tagged_content(size_value, remaining_depth),
                    7 => self.decode_to_simple_value(size_value, additional_info),
                    _ => Err(DecoderError::UnsupportedMajorType),
                }
            }
            _ => Err(DecoderError::IncompleteCborData),
        }
    }

    fn read_bytes(&mut self, num_bytes: usize) -> Option<&[u8]> {
        if num_bytes > self.remaining_cbor.len() {
            None
        } else {
            let (left, right) = self.remaining_cbor.split_at(num_bytes);
            self.remaining_cbor = right;
            Some(left)
        }
    }

    fn read_variadic_length_integer(&mut self, additional_info: u8) -> Result<u64, DecoderError> {
        let additional_bytes_num = match additional_info {
            0..=Constants::ADDITIONAL_INFORMATION_MAX_INT => return Ok(additional_info as u64),
            Constants::ADDITIONAL_INFORMATION_1_BYTE => 1,
            Constants::ADDITIONAL_INFORMATION_2_BYTES => 2,
            Constants::ADDITIONAL_INFORMATION_4_BYTES => 4,
            Constants::ADDITIONAL_INFORMATION_8_BYTES => 8,
            _ => return Err(DecoderError::UnknownAdditionalInfo),
        };
        match self.read_bytes(additional_bytes_num) {
            Some(bytes) => {
                let mut size_value = 0u64;
                for byte in bytes {
                    size_value <<= 8;
                    size_value += *byte as u64;
                }
                if ((additional_bytes_num == 1 && size_value < 24)
                    || size_value < (1u64 << (8 * (additional_bytes_num >> 1))))
                    && !self.non_strict
                {
                    Err(DecoderError::NonMinimalCborEncoding)
                } else {
                    Ok(size_value)
                }
            }
            None => Err(DecoderError::IncompleteCborData),
        }
    }

    fn decode_value_to_unsigned(&self, size_value: u64) -> Result<Value, DecoderError> {
        Ok(cbor_unsigned!(size_value))
    }

    fn decode_value_to_negative(&self, size_value: u64) -> Result<Value, DecoderError> {
        Ok(Value::Negative(-(size_value as i128) - 1))
    }

    fn read_byte_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> {
        match self.read_bytes(size_value as usize) {
            Some(bytes) => Ok(cbor_bytes_lit!(bytes)),
            None => Err(DecoderError::IncompleteCborData),
        }
    }

    fn read_text_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> {
        match self.read_bytes(size_value as usize) {
            Some(bytes) => match str::from_utf8(bytes) {
                Ok(s) => Ok(cbor_text!(s)),
                Err(_) => Err(DecoderError::InvalidUtf8),
            },
            None => Err(DecoderError::IncompleteCborData),
        }
    }

    fn read_array_content(
        &mut self,
        size_value: u64,
        remaining_depth: Option<i8>,
    ) -> Result<Value, DecoderError> {
        // Don't set the capacity already, it is an unsanitized input.
        let mut value_array = Vec::new();
        for _ in 0..size_value {
            value_array.push(self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?);
        }
        Ok(cbor_array_vec!(value_array))
    }

    fn read_map_content(
        &mut self,
        size_value: u64,
        remaining_depth: Option<i8>,
    ) -> Result<Value, DecoderError> {
        let mut value_map = Vec::<(Value, Value)>::new();
        for _ in 0..size_value {
            let key = self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?;
            if let Some(last_item) = value_map.last() {
                if last_item.0 >= key && !self.non_strict {
                    return Err(DecoderError::OutOfOrderKey);
                }
            }
            value_map.push((
                key,
                self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?,
            ));
        }
        Ok(cbor_map_collection!(value_map))
    }

    fn read_tagged_content(
        &mut self,
        tag_value: u64,
        remaining_depth: Option<i8>,
    ) -> Result<Value, DecoderError> {
        let inner_value = self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?;
        Ok(cbor_tagged!(tag_value, inner_value))
    }

    fn decode_to_simple_value(
        &self,
        size_value: u64,
        additional_info: u8,
    ) -> Result<Value, DecoderError> {
        if additional_info > Constants::ADDITIONAL_INFORMATION_MAX_INT
            && additional_info != Constants::ADDITIONAL_INFORMATION_1_BYTE
            && !self.non_strict
        {
            // TODO(kaczmarczyck) the chromium C++ reference allows equality to 24 here, why?
            // Also, why not just disallow ANY additional_info != size_value?
            return Err(DecoderError::UnsupportedFloatingPointValue);
        }
        match SimpleValue::from_integer(size_value) {
            Some(simple_value) => Ok(Value::Simple(simple_value)),
            None if self.non_strict => Ok(Value::Simple(SimpleValue::Undefined)),
            None => Err(DecoderError::UnsupportedSimpleValue),
        }
    }
}

#[cfg(test)]
mod test {
    use alloc::vec;

    use super::*;
    use crate::{
        cbor_array, cbor_bytes, cbor_false, cbor_int, cbor_map, cbor_null, cbor_true,
        cbor_undefined,
    };

    #[test]
    fn test_read_unsigned() {
        let cases = vec![
            (0, vec![0x00]),
            (1, vec![0x01]),
            (10, vec![0x0A]),
            (23, vec![0x17]),
            (24, vec![0x18, 0x18]),
            (255, vec![0x18, 0xFF]),
            (256, vec![0x19, 0x01, 0x00]),
            (65535, vec![0x19, 0xFF, 0xFF]),
            (65536, vec![0x1A, 0x00, 0x01, 0x00, 0x00]),
            (0xFFFFFFFF, vec![0x1A, 0xFF, 0xFF, 0xFF, 0xFF]),
            (
                0x100000000,
                vec![0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
            ),
            (
                core::i64::MAX,
                vec![0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
            ),
        ];
        for (unsigned, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(cbor_int!(unsigned)));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_unsigned_non_minimum_byte_length() {
        let encodings = vec![
            // Uint 23 encoded with 1 byte.
            vec![0x18, 0x17],
            // Uint 255 encoded with 2 bytes.
            vec![0x19, 0x00, 0xff],
            // Uint 65535 encoded with 4 bytes.
            vec![0x1a, 0x00, 0x00, 0xff, 0xff],
            // Uint 4294967295 encoded with 8 bytes.
            vec![0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff],
            // When decoding byte has more than one syntax error, the first syntax
            // error encountered during deserialization is returned as the error code.
            vec![
                0xa2, // map with non-minimally encoded key
                0x17, // key 24
                0x61, 0x42, // value :"B"
                0x18, 0x17, // key 23 encoded with extra byte
                0x61, 0x45, // value "E"
            ],
            vec![
                0xa2, // map with out of order and non-minimally encoded key
                0x18, 0x17, // key 23 encoded with extra byte
                0x61, 0x45, // value "E"
                0x17, // key 23
                0x61, 0x42, // value :"B"
            ],
            vec![
                0xa2, // map with duplicate non-minimally encoded key
                0x18, 0x17, // key 23 encoded with extra byte
                0x61, 0x45, // value "E"
                0x18, 0x17, // key 23 encoded with extra byte
                0x61, 0x42, // value :"B"
            ],
        ];
        for encoding in encodings {
            assert_eq!(read(&encoding), Err(DecoderError::NonMinimalCborEncoding));
        }
    }

    #[test]
    fn test_read_negative() {
        let cases = vec![
            (-1, vec![0x20]),
            (-24, vec![0x37]),
            (-25, vec![0x38, 0x18]),
            (-256, vec![0x38, 0xFF]),
            (-1000, vec![0x39, 0x03, 0xE7]),
            (-1000000, vec![0x3A, 0x00, 0x0F, 0x42, 0x3F]),
            (-4294967296, vec![0x3A, 0xFF, 0xFF, 0xFF, 0xFF]),
            (
                core::i64::MIN,
                vec![0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
            ),
        ];
        for (negative, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(cbor_int!(negative)));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_byte_string() {
        let cases = vec![
            (Vec::new(), vec![0x40]),
            (
                vec![0x01, 0x02, 0x03, 0x04],
                vec![0x44, 0x01, 0x02, 0x03, 0x04],
            ),
        ];
        for (byte_string, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(cbor_bytes!(byte_string)));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_text_string() {
        let unicode_3byte = vec![0xE6, 0xB0, 0xB4];
        let cases = vec![
            ("", vec![0x60]),
            ("a", vec![0x61, 0x61]),
            ("IETF", vec![0x64, 0x49, 0x45, 0x54, 0x46]),
            ("\"\\", vec![0x62, 0x22, 0x5C]),
            ("ü", vec![0x62, 0xC3, 0xBC]),
            (
                core::str::from_utf8(&unicode_3byte).unwrap(),
                vec![0x63, 0xE6, 0xB0, 0xB4],
            ),
            ("𐅑", vec![0x64, 0xF0, 0x90, 0x85, 0x91]),
        ];
        for (text_string, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(cbor_text!(text_string)));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_text_string_with_nul() {
        let cases = vec![
            (
                "string_without_nul",
                vec![
                    0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x6F,
                    0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C,
                ],
            ),
            (
                "nul_terminated_string\0",
                vec![
                    0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, 0x74,
                    0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00,
                ],
            ),
            (
                "embedded\0nul",
                vec![
                    0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75, 0x6C,
                ],
            ),
            (
                "trailing_nuls\0\0",
                vec![
                    0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75, 0x6C,
                    0x73, 0x00, 0x00,
                ],
            ),
        ];
        for (text_string, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(cbor_text!(text_string)));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_text_string_with_invalid_byte_sequence_after_nul() {
        assert_eq!(
            read(&vec![0x63, 0x00, 0x00, 0xA6]),
            Err(DecoderError::InvalidUtf8)
        );
    }

    #[test]
    fn test_read_array() {
        let value_vec: Vec<_> = (1..26).collect();
        let mut test_cbor = vec![
            0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18,
            0x19,
        ];
        assert_eq!(read(&test_cbor.clone()), Ok(cbor_array_vec!(value_vec)));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map() {
        let value_map = cbor_map! {
            24 => "abc",
            "" => ".",
            "b" => "B",
            "aa" => "AA",
        };
        let mut test_cbor = vec![
            0xa4, // map with 4 key value pairs:
            0x18, 0x18, // 24
            0x63, 0x61, 0x62, 0x63, // "abc"
            0x60, // ""
            0x61, 0x2e, // "."
            0x61, 0x62, // "b"
            0x61, 0x42, // "B"
            0x62, 0x61, 0x61, // "aa"
            0x62, 0x41, 0x41, // "AA"
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map_with_unsigned_keys() {
        let value_map = cbor_map! {
            1 => "a",
            9 => "b",
            999 => "c",
            1111 => "d",
        };
        let mut test_cbor = vec![
            0xa4, // map with 4 key value pairs:
            0x01, // key : 1
            0x61, 0x61, // value : "a"
            0x09, // key : 9
            0x61, 0x62, // value : "b"
            0x19, 0x03, 0xE7, // key : 999
            0x61, 0x63, // value "c"
            0x19, 0x04, 0x57, // key : 1111
            0x61, 0x64, // value : "d"
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map_with_negative_keys() {
        let value_map = cbor_map! {
            -1 => 1,
            -2 => 2,
            -100 => 3,
        };
        let mut test_cbor = vec![
            0xA3, // map with 3 key value pairs
            0x20, // key : -1
            0x01, // value : 1
            0x21, // key : -2
            0x02, // value : 2
            0x38, 0x63, // key : -100
            0x03, // value : 3
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map_with_array() {
        let value_map = cbor_map! {
            "a" => 1,
            "b" => cbor_array![2, 3],
        };
        let mut test_cbor = vec![
            0xa2, // map of 2 pairs
            0x61, 0x61, // "a"
            0x01, 0x61, 0x62, // "b"
            0x82, // array with 2 elements
            0x02, 0x03,
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map_with_text_string_keys() {
        let value_map = cbor_map! {
            "k" => "v",
            "foo" => "bar",
        };
        let mut test_cbor = vec![
            0xa2, // map of 2 pairs
            0x61, b'k', // text string "k"
            0x61, b'v', 0x63, b'f', b'o', b'o', // text string "foo"
            0x63, b'b', b'a', b'r',
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_map_with_byte_string_keys() {
        let value_map = cbor_map! {
            b"k" => b"v",
            b"foo" => b"bar",
        };
        let mut test_cbor = vec![
            0xa2, // map of 2 pairs
            0x41, b'k', // text string "k"
            0x41, b'v', 0x43, b'f', b'o', b'o', // text string "foo"
            0x43, b'b', b'a', b'r',
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_nested_map() {
        let value_map = cbor_map! {
            "a" => 1,
            "b" => cbor_map! {
                "c" => 2,
                "d" => 3,
            },
        };
        let mut test_cbor = vec![
            0xa2, // map of 2 pairs
            0x61, 0x61, 0x01, // "a"
            0x61, 0x62, // "b"
            0xa2, // map of 2 pairs
            0x61, 0x63, 0x02, // "c"
            0x61, 0x64, 0x03, // "d"
        ];
        assert_eq!(read(&test_cbor), Ok(value_map));
        test_cbor.push(0x01);
        assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData));
    }

    #[test]
    fn test_read_tagged() {
        let cases = vec![
            (cbor_tagged!(6, cbor_int!(0x42)), vec![0xc6, 0x18, 0x42]),
            (cbor_tagged!(1, cbor_true!()), vec![0xc1, 0xf5]),
            (
                cbor_tagged!(
                    1000,
                    cbor_map! {
                        "a" => 1,
                        "b" => cbor_array![2, 3],
                    }
                ),
                vec![
                    0xd9, 0x03, 0xe8, 0xa2, // map of 2 pairs
                    0x61, 0x61, // "a"
                    0x01, 0x61, 0x62, // "b"
                    0x82, // array with 2 elements
                    0x02, 0x03,
                ],
            ),
        ];
        for (value, mut cbor) in cases {
            assert_eq!(read(&cbor), Ok(value));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_integer_out_of_range() {
        let cases = vec![
            // The positive case is impossible since we support u64.
            // vec![0x1B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            vec![0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Ok(Value::Negative(-9223372036854775809)));
        }
    }

    #[test]
    fn test_read_simple_value() {
        let cases = vec![
            (cbor_false!(), vec![0xF4]),
            (cbor_true!(), vec![0xF5]),
            (cbor_null!(), vec![0xF6]),
            (cbor_undefined!(), vec![0xF7]),
        ];
        for (simple, mut cbor) in cases {
            assert_eq!(read(&cbor.clone()), Ok(simple));
            cbor.push(0x01);
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_unsupported_floating_point_numbers() {
        let cases = vec![
            vec![0xF9, 0x10, 0x00],
            vec![0xFA, 0x10, 0x00, 0x00, 0x00],
            vec![0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
        ];
        for cbor in cases {
            assert_eq!(
                read(&cbor),
                Err(DecoderError::UnsupportedFloatingPointValue)
            );
        }
    }

    #[test]
    fn test_read_incomplete_cbor_data_error() {
        let cases = vec![
            vec![0x19, 0x03],
            vec![0x44, 0x01, 0x02, 0x03],
            vec![0x65, 0x49, 0x45, 0x54, 0x46],
            vec![0x82, 0x02],
            vec![0xA2, 0x61, 0x61, 0x01],
            vec![0x18],
            vec![0x99],
            vec![0xBA],
            vec![0x5B],
            vec![0x3B],
            vec![0x99, 0x01],
            vec![0xBA, 0x01, 0x02, 0x03],
            vec![0x3B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData));
        }
    }

    #[test]
    fn test_read_unknown_additional_info_error() {
        let cases = vec![
            vec![0x7C, 0x49, 0x45, 0x54, 0x46],
            vec![0x7D, 0x22, 0x5C],
            vec![0x7E, 0xC3, 0xBC],
            vec![0x7F, 0xE6, 0xB0, 0xB4],
            vec![0xFC],
            vec![0xFD],
            vec![0xFE],
            vec![0xFF],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::UnknownAdditionalInfo));
        }
    }

    #[test]
    fn test_read_too_much_nesting_error() {
        let cases = vec![
            vec![0x18, 0x64],
            vec![0x44, 0x01, 0x02, 0x03, 0x04],
            vec![0x64, 0x49, 0x45, 0x54, 0x46],
            vec![0x80],
            vec![0xA0],
        ];
        for cbor in cases {
            let mut reader = Reader::new(&cbor);
            assert!(reader.decode_complete_data_item(Some(0)).is_ok());
        }
        let map_cbor = vec![
            0xa2, // map of 2 pairs
            0x61, 0x61, // "a"
            0x01, 0x61, 0x62, // "b"
            0x82, // array with 2 elements
            0x02, 0x03,
        ];
        let mut reader = Reader::new(&map_cbor);
        assert_eq!(
            reader.decode_complete_data_item(Some(1)),
            Err(DecoderError::TooMuchNesting)
        );
        reader = Reader::new(&map_cbor);
        assert!(reader.decode_complete_data_item(Some(2)).is_ok());
    }

    #[test]
    fn test_read_out_of_order_key_error() {
        let cases = vec![
            vec![
                0xa2, // map with 2 keys with same major type and length
                0x61, 0x62, // key "b"
                0x61, 0x42, // value "B"
                0x61, 0x61, // key "a" (out of order byte-wise lexically)
                0x61, 0x45, // value "E"
            ],
            vec![
                0xa2, // map with 2 keys with different major type
                0x61, 0x62, // key "b"
                0x02, // value 2
                // key 1000 (out of order since lower major type sorts first)
                0x19, 0x03, 0xe8, 0x61, 0x61, // value a
            ],
            vec![
                0xa2, // map with 2 keys with same major type
                0x19, 0x03, 0xe8, // key 1000  (out of order due to longer length)
                0x61, 0x61, //value "a"
                0x0a, // key 10
                0x61, 0x62, // value "b"
            ],
            vec![
                0xa2, // map with 2 text string keys
                0x62, b'a', b'a', // key text string "aa"
                // (out of order due to longer length)
                0x02, 0x61, b'b', // key "b"
                0x01,
            ],
            vec![
                0xa2, // map with 2 byte string keys
                0x42, b'x', b'x', // key byte string "xx"
                // (out of order due to longer length)
                0x02, 0x41, b'y', // key byte string "y"
                0x01,
            ],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::OutOfOrderKey));
        }
    }

    #[test]
    fn test_read_duplicate_key_error() {
        let map_with_duplicate_key = vec![
            0xa6, // map of 6 pairs:
            0x60, // ""
            0x61, 0x2e, // "."
            0x61, 0x62, // "b"
            0x61, 0x42, // "B"
            0x61, 0x62, // "b" (Duplicate key)
            0x61, 0x43, // "C"
            0x61, 0x64, // "d"
            0x61, 0x44, // "D"
            0x61, 0x65, // "e"
            0x61, 0x44, // "D"
            0x62, 0x61, 0x61, // "aa"
            0x62, 0x41, 0x41, // "AA"
        ];
        assert_eq!(
            read(&map_with_duplicate_key),
            Err(DecoderError::OutOfOrderKey)
        );
    }

    #[test]
    fn test_read_incorrect_string_encoding_error() {
        let cases = vec![
            vec![0x63, 0xED, 0x9F, 0xBF],
            vec![0x63, 0xEE, 0x80, 0x80],
            vec![0x63, 0xEF, 0xBF, 0xBD],
        ];
        for cbor in cases {
            assert!(read(&cbor).is_ok());
        }
        let impossible_utf_byte = vec![0x64, 0xFE, 0xFE, 0xFF, 0xFF];
        assert_eq!(read(&impossible_utf_byte), Err(DecoderError::InvalidUtf8));
    }

    #[test]
    fn test_read_extraneous_cbor_data_error() {
        let cases = vec![
            vec![0x19, 0x03, 0x05, 0x00],
            vec![0x44, 0x01, 0x02, 0x03, 0x04, 0x00],
            vec![0x64, 0x49, 0x45, 0x54, 0x46, 0x00],
            vec![0x82, 0x01, 0x02, 0x00],
            vec![0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData));
        }
    }

    #[test]
    fn test_read_unsupported_simple_type() {
        let cases = vec![
            vec![0xE0],
            vec![0xF3],
            vec![0xF8, 0x18],
            vec![0xF8, 0x1C],
            vec![0xF8, 0x1D],
            vec![0xF8, 0x1E],
            vec![0xF8, 0x1F],
            vec![0xF8, 0x20],
            vec![0xF8, 0xFF],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::UnsupportedSimpleValue));
        }
    }

    #[test]
    fn test_read_super_long_content_dont_crash() {
        let cases = vec![
            vec![0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
            vec![0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
        ];
        for cbor in cases {
            assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData));
        }
    }
}
