// BYTES (8 bits)

pub(crate) fn bytes_xor(arr1: &[u8], arr2: &[u8]) -> Box<[u8]> {
    arr1.iter().zip(arr2.iter()).map(|(&x1, &x2)| x1 ^ x2).collect()
}


// DWORDS (32 bits)

pub(crate) fn bytes_to_dwords(bytes: &[u8]) -> Box<[u32]> {
    let mut dwords = Vec::<u32>::with_capacity(bytes.len() / 4);
    for i in 0..bytes.len() / 4 {
        dwords.push(u32::from_be_bytes(bytes[i * 4..i * 4 + 4].try_into().unwrap()));
    }

    dwords.into()
}


pub(crate) fn dwords_add(arr1: &[u32], arr2: &[u32]) -> Box<[u32]> {
    arr1.iter().zip(arr2.iter()).map(|(&x1, &x2)| x1.wrapping_add(x2)).collect()
}


pub(crate) fn dwords_xor(arr1: &[u32], arr2: &[u32]) -> Box<[u32]> {
    arr1.iter().zip(arr2.iter()).map(|(&x1, &x2)| x1 ^ x2).collect()
}


pub(crate) fn dwords_to_bytes(words: &[u32]) -> Box<[u8]> {
    let mut bytes = Vec::<u8>::with_capacity(words.len() * 4);
    for word in words {
        bytes.append(&mut word.to_be_bytes().into());
    }

    bytes.into()
}


pub(crate) fn dwords_as_qwords(words: &[u32]) -> Box<[u64]> {
    words.iter().map(|&x1| x1 as u64).collect()
}


// QWORDS (64 bits)

pub(crate) fn bytes_to_qwords(bytes: &[u8]) -> Box<[u64]> {
    let mut qwords = Vec::<u64>::with_capacity(bytes.len() / 8);
    for i in 0..bytes.len() / 8 {
        qwords.push(u64::from_be_bytes(bytes[i * 8..i * 8 + 8].try_into().unwrap()));
    }

    qwords.into()
}


pub(crate) fn qwords_add(arr1: &[u64], arr2: &[u64]) -> Box<[u64]> {
    arr1.iter().zip(arr2.iter()).map(|(&x1, &x2)| x1.wrapping_add(x2)).collect()
}


pub(crate) fn qwords_to_bytes(words: &[u64]) -> Box<[u8]> {
    let mut bytes = Vec::<u8>::with_capacity(words.len() * 8);
    for word in words {
        bytes.append(&mut word.to_be_bytes().into());
    }

    bytes.into()
}


pub(crate) fn qwords_to_dwords(words: &[u64]) -> Box<[u32]> {
    words.iter().map(|&x1| x1 as u32).collect()
}


/// 字节数组转换为十六进制字符串（Convert Byte Array to Hex String）
///
/// # 参数（Arguments）
///
/// * bytes - 字节数组（Byte Array）
///
/// # 示例（Examples）
///
/// ```rust
/// use neuedu_cryptos::common::bytes_to_hexstring;
///
/// const BYTES: [u8; 32] = [
///     0x66, 0xC7, 0xF0, 0xF4, 0x62, 0xEE, 0xED, 0xD9,
///     0xD1, 0xF2, 0xD4, 0x6B, 0xDC, 0x10, 0xE4, 0xE2,
///     0x41, 0x67, 0xC4, 0x87, 0x5C, 0xF2, 0xF7, 0xA2,
///     0x29, 0x7D, 0xA0, 0x2B, 0x8F, 0x4B, 0xA8, 0xE0,
/// ];
///
/// let hex_string = bytes_to_hexstring(&BYTES);
///
/// assert_eq!(hex_string, "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0");
/// ```
pub fn bytes_to_hexstring(bytes: &[u8]) -> String {
    bytes.iter().map(|x| format!("{x:02x}")).collect()
}
