
use std::time::Instant;

pub fn usize_to_u16_be_bytes(n: usize) -> [u8; 2] {
    (n as u16).to_be_bytes()
}

pub fn usize_to_u16_le_bytes(n: usize) -> [u8; 2] {
    (n as u16).to_be_bytes()
}

pub fn u16_to_hex_be_bytes(n: u16) -> [u8; 2] {
    (n as u16).to_be_bytes()
}

pub fn u16_to_hex_le_bytes(n: u16) -> [u8; 2] {
    (n as u16).to_le_bytes()
}

pub fn calc_crc8_smbus(c: &[u8]) -> u8 {
    let crc8_smbus = crc::Crc::<u8>::new(&crc::CRC_8_SMBUS);
    let checksum = crc8_smbus.checksum(c);
    return checksum;
}

pub fn calc_crc8_itu(c: &[u8]) -> u8 {
    let crc8_itu_alg = crc::Crc::<u8>::new(&crc::CRC_8_I_432_1);
    let checksum = crc8_itu_alg.checksum(c);
    return checksum;
}

pub fn elapsed_millis(start_at: Instant) -> u64 {
    start_at.elapsed().as_millis() as u64
}

#[cfg(test)]
mod test {
    use anyhow::Ok;

    use crate::serial_core::utils::{calc_crc8_itu, calc_crc8_smbus};

    #[test]
    fn test_crc8_itu() -> anyhow::Result<()> {
        let req_vec = vec![0x55, 0xAA, 0x09, 0x00, 0x34, 0x00, 0xFB, 0x00, 0x1C, 0x00, 0x00, 0x18, 0x00];
        let checksum = calc_crc8_itu(req_vec.as_slice());
        assert_eq!(checksum, 0x7A);

        Ok(())
    }

    #[test]
    fn test_crc8_smbus() -> anyhow::Result<()> {
        let req_vec = vec![0x55, 0xAA, 0x09, 0x00, 0x34, 0x00, 0xFB, 0x00, 0x1C, 0x00, 0x00, 0x18, 0x00];
        let checksum = calc_crc8_smbus(req_vec.as_slice());
        assert_eq!(checksum, 0x2F);

        Ok(())
    }
}