//! `generic-array` integration with `Uint`.
// TODO(tarcieri): completely phase out `generic-array` when const generics are powerful enough

use crate::{ArrayDecoding, ArrayEncoding, ByteArray};
use generic_array::{typenum, GenericArray};

macro_rules! impl_uint_array_encoding {
    ($(($uint:ident, $bytes:path)),+) => {
        $(
            impl ArrayEncoding for super::$uint {
                type ByteSize = $bytes;

                #[inline]
                fn from_be_byte_array(bytes: ByteArray<Self>) -> Self {
                    Self::from_be_slice(&bytes)
                }

                #[inline]
                fn from_le_byte_array(bytes: ByteArray<Self>) -> Self {
                    Self::from_le_slice(&bytes)
                }

                #[inline]
                fn to_be_byte_array(&self) -> ByteArray<Self> {
                    let mut result = GenericArray::default();
                    self.write_be_bytes(&mut result);
                    result
                }

                #[inline]
                fn to_le_byte_array(&self) -> ByteArray<Self> {
                    let mut result = GenericArray::default();
                    self.write_le_bytes(&mut result);
                    result
                }
            }

            impl ArrayDecoding for GenericArray<u8, $bytes> {
                type Output = super::$uint;

                fn into_uint_be(self) -> Self::Output {
                    Self::Output::from_be_byte_array(self)
                }

                fn into_uint_le(self) -> Self::Output {
                    Self::Output::from_le_byte_array(self)
                }
            }
        )+
     };
}

// TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits.
impl_uint_array_encoding! {
    (U64, typenum::U8),
    (U128, typenum::U16),
    (U192, typenum::U24),
    (U256, typenum::U32),
    (U384, typenum::U48),
    (U448, typenum::U56),
    (U512, typenum::U64),
    (U576, typenum::U72),
    (U768, typenum::U96),
    (U896, typenum::U112),
    (U1024, typenum::U128),
    (U1536, typenum::U192),
    (U1792, typenum::U224),
    (U2048, typenum::U256),
    (U3072, typenum::U384),
    (U3584, typenum::U448),
    (U4096, typenum::U512),
    (U6144, typenum::U768),
    (U8192, typenum::U1024)
}

#[cfg(target_pointer_width = "32")]
impl_uint_array_encoding! {
    (U224, typenum::U28), // For NIST P-224
    (U544, typenum::U68)  // For NIST P-521
}

#[cfg(test)]
mod tests {
    use crate::{ArrayDecoding, ArrayEncoding, Limb};
    use hex_literal::hex;

    #[cfg(target_pointer_width = "32")]
    use crate::U64 as UintEx;

    #[cfg(target_pointer_width = "64")]
    use crate::U128 as UintEx;

    /// Byte array that corresponds to `UintEx`
    type ByteArray = crate::ByteArray<UintEx>;

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn from_be_byte_array() {
        let n = UintEx::from_be_byte_array(hex!("0011223344556677").into());
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn from_be_byte_array() {
        let n = UintEx::from_be_byte_array(hex!("00112233445566778899aabbccddeeff").into());
        assert_eq!(
            n.as_limbs(),
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
        );
    }

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn from_le_byte_array() {
        let n = UintEx::from_le_byte_array(hex!("7766554433221100").into());
        assert_eq!(n.as_limbs(), &[Limb(0x44556677), Limb(0x00112233)]);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn from_le_byte_array() {
        let n = UintEx::from_le_byte_array(hex!("ffeeddccbbaa99887766554433221100").into());
        assert_eq!(
            n.as_limbs(),
            &[Limb(0x8899aabbccddeeff), Limb(0x0011223344556677)]
        );
    }

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn to_be_byte_array() {
        let expected_bytes = ByteArray::from(hex!("0011223344556677"));
        let actual_bytes = UintEx::from_be_byte_array(expected_bytes).to_be_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn to_be_byte_array() {
        let expected_bytes = ByteArray::from(hex!("00112233445566778899aabbccddeeff"));
        let actual_bytes = UintEx::from_be_byte_array(expected_bytes).to_be_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn to_le_byte_array() {
        let expected_bytes = ByteArray::from(hex!("7766554433221100"));
        let actual_bytes = UintEx::from_le_byte_array(expected_bytes).to_le_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn to_le_byte_array() {
        let expected_bytes = ByteArray::from(hex!("ffeeddccbbaa99887766554433221100"));
        let actual_bytes = UintEx::from_le_byte_array(expected_bytes).to_le_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn into_uint_be() {
        let expected_bytes = ByteArray::from(hex!("0011223344556677"));
        let actual_bytes = expected_bytes.into_uint_be().to_be_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn into_uint_be() {
        let expected_bytes = ByteArray::from(hex!("00112233445566778899aabbccddeeff"));
        let actual_bytes = expected_bytes.into_uint_be().to_be_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "32")]
    fn into_uint_le() {
        let expected_bytes = ByteArray::from(hex!("7766554433221100"));
        let actual_bytes = expected_bytes.into_uint_le().to_le_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn into_uint_le() {
        let expected_bytes = ByteArray::from(hex!("ffeeddccbbaa99887766554433221100"));
        let actual_bytes = expected_bytes.into_uint_le().to_le_byte_array();
        assert_eq!(expected_bytes, actual_bytes);
    }
}
