//! Equivalence tests between `base64` crate and `base64ct`.

#![cfg(feature = "std")]
// TODO(tarcieri): fix `base64` crate deprecations
// warning: use of deprecated function `base64::encode`: Use Engine::encode
#![allow(deprecated)]

use base64ct::{Base64 as Base64ct, Encoding};
use proptest::{prelude::*, string::*};
use std::iter;

/// Incremental Base64 decoder.
type Decoder<'a> = base64ct::Decoder<'a, Base64ct>;

/// Incremental Base64 encoder.
type Encoder<'a> = base64ct::Encoder<'a, Base64ct>;

proptest! {
    /// Ensure `base64ct` decodes data encoded by `base64` ref crate
    #[test]
    fn decode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) {
        let encoded = base64::encode(&bytes);
        let decoded = Base64ct::decode_vec(&encoded);
        prop_assert_eq!(Ok(bytes), decoded);
    }

    /// Ensure that `base64ct`'s incremental decoder is able to decode randomly
    /// generated inputs encoded by the `base64` ref crate
    #[test]
    fn decode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) {
        let encoded = base64::encode(&bytes);
        let chunk_size = match chunk_size % bytes.len() {
            0 => 1,
            n => n
        };

        let mut buffer = [0u8; 384];
        let mut decoder = Decoder::new(encoded.as_bytes()).unwrap();
        let mut remaining_len = decoder.remaining_len();

        for chunk in bytes.chunks(chunk_size) {
            prop_assert!(!decoder.is_finished());

            let decoded = decoder.decode(&mut buffer[..chunk.len()]);
            prop_assert_eq!(Ok(chunk), decoded);

            remaining_len -= decoded.unwrap().len();
            prop_assert_eq!(remaining_len, decoder.remaining_len());
        }

        prop_assert!(decoder.is_finished());
        prop_assert_eq!(decoder.remaining_len(), 0);
    }

    #[test]
    fn decode_incremental_wrapped(
        bytes in bytes_regex(".{1,256}").unwrap(),
        line_width in 4..128usize,
        chunk_size in 1..256usize
    ) {
        for line_ending in ["\r", "\n", "\r\n"] {
            let encoded = base64::encode(&bytes);

            let mut encoded_wrapped = Vec::new();
            let mut lines = encoded.as_bytes().chunks_exact(line_width);

            for line in &mut lines {
                encoded_wrapped.extend_from_slice(line);
                encoded_wrapped.extend_from_slice(line_ending.as_bytes());
            }

            let last = lines.remainder();

            if last.is_empty() {
                encoded_wrapped.truncate(encoded_wrapped.len() - line_ending.len());
            } else {
                encoded_wrapped.extend_from_slice(last);
            }

            let chunk_size = match chunk_size % bytes.len() {
                0 => 1,
                n => n
            };

            let mut buffer = [0u8; 384];
            let mut decoder = Decoder::new_wrapped(&encoded_wrapped, line_width).unwrap();
            let mut remaining_len = decoder.remaining_len();

            for chunk in bytes.chunks(chunk_size) {
                prop_assert!(!decoder.is_finished());

                let decoded = decoder.decode(&mut buffer[..chunk.len()]);
                prop_assert_eq!(Ok(chunk), decoded);

                remaining_len -= decoded.unwrap().len();
                prop_assert_eq!(remaining_len, decoder.remaining_len());
            }

            prop_assert!(decoder.is_finished());
            prop_assert_eq!(decoder.remaining_len(), 0);
        }
    }

    /// Ensure `base64ct` and `base64` ref crate decode randomly generated
    /// inputs equivalently.
    ///
    /// Inputs are selected to be valid characters in the standard Base64
    /// padded alphabet, but are not necessarily valid Base64.
    #[test]
    fn decode_random(base64ish in string_regex("[A-Za-z0-9+/]{0,256}").unwrap()) {
        let base64ish_padded = match base64ish.len() % 4 {
            0 => base64ish,
            n => {
                let padding_len = 4 - n;
                base64ish + &iter::repeat("=").take(padding_len).collect::<String>()
            }
        };

        let decoded_ct = Base64ct::decode_vec(&base64ish_padded).ok();
        let decoded_ref = base64::decode(&base64ish_padded).ok();
        prop_assert_eq!(decoded_ct, decoded_ref);
    }

    /// Ensure `base64ct` and the `base64` ref crate encode randomly generated
    /// inputs equivalently.
    #[test]
    fn encode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) {
        let encoded_ct = Base64ct::encode_string(&bytes);
        let encoded_ref = base64::encode(&bytes);
        prop_assert_eq!(encoded_ct, encoded_ref);
    }

    /// Ensure that `base64ct`'s incremental encoder is able to encode randomly
    /// generated inputs which match what's encoded by the `base64` ref crate
    #[test]
    fn encode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) {
        let expected = base64::encode(&bytes);
        let chunk_size = match chunk_size % bytes.len() {
            0 => 1,
            n => n
        };

        let mut buffer = [0u8; 1024];
        let mut encoder = Encoder::new(&mut buffer).unwrap();

        for chunk in bytes.chunks(chunk_size) {
            encoder.encode(chunk).unwrap();
        }

        prop_assert_eq!(expected, encoder.finish().unwrap());
    }
}
