use core::fmt::Debug;

use crate::{wire, Deserialize, Serialize};

#[track_caller]
pub fn test_serialize_reversibility<'de, T: PartialEq + Serialize + Deserialize<'de> + Debug>(
    buffer: &'de mut [u8],
    value: &T,
) {
    extern crate std;

    let len = wire::to_slice(value, buffer).expect("Serialize failed");
    let result: T = wire::from_slice(&buffer[..len]).expect("Deserialize failed");
    if result != *value {
        std::eprintln!("Serialized value is not equal to deserialized one:");
        std::eprintln!("* Original: {value:?}");
        std::eprintln!("* Deserialized: {result:?}");

        std::eprintln!("Message of {len} bytes:");
        for i in (0..len).step_by(16) {
            std::eprint!("{i:02x}: ");
            for j in 0..16 {
                if j != 0 {
                    std::eprint!(" ");
                }

                if i + j < len {
                    std::eprint!("{:02X}", buffer[i + j]);
                } else {
                    std::eprint!("  ");
                }
            }
            std::eprint!(" | ");
            for j in 0..16 {
                if i + j < len {
                    let c = buffer[i + j];
                    let c = if c.is_ascii_graphic() { c as char } else { '.' };
                    std::eprint!("{}", c);
                }
            }
            std::eprintln!();
        }

        panic!("Equality test failed")
    }
}
