use kcan::{
    CanFrame, CanId, DirectCommand, MitCommand, MotorModel, RobStrideCommand, RobStrideModel,
    direct_command_frame, mit_command_frame, robstride_command_frame, robstride_status_query_frame,
};

#[test]
fn root_exports_build_common_frames() -> kcan::Result<()> {
    let mit = mit_command_frame(MotorModel::Ak60_6, 0x03, MitCommand::neutral())?;
    assert_eq!(mit.id().raw(), 0x0803);
    assert_eq!(mit.len(), 8);

    let direct = direct_command_frame(0x03, DirectCommand::Velocity(1_000))?;
    assert_eq!(direct.id().raw(), 0x0303);
    assert_eq!(direct.data(), &[0x00, 0x00, 0x03, 0xE8]);

    let status = robstride_status_query_frame(0x01)?;
    let status_from_command =
        robstride_command_frame(RobStrideModel::Rs01, 0x01, RobStrideCommand::StatusQuery)?;
    assert_eq!(status_from_command, status);
    assert_eq!(status.id().raw(), 0x501);

    Ok(())
}

#[test]
fn can_ids_and_frames_have_stable_display_output() -> kcan::Result<()> {
    let standard = CanId::standard(0x123)?;
    let extended = CanId::extended(0x501)?;
    let frame = CanFrame::new(extended, &[0x0A, 0xB0])?;

    assert_eq!(standard.kind_name(), "standard");
    assert_eq!(extended.kind_name(), "extended");
    assert_eq!(standard.to_string(), "standard 0x123");
    assert_eq!(extended.to_string(), "extended 0x501");
    assert_eq!(frame.to_string(), "extended 0x501 len=2 data=0A B0");
    assert_eq!(standard.to_string().parse::<CanId>().unwrap(), standard);
    assert_eq!(extended.to_string().parse::<CanId>().unwrap(), extended);
    assert_eq!("s:0x123".parse::<CanId>().unwrap(), standard);
    assert_eq!("e:0x501".parse::<CanId>().unwrap(), extended);
    assert!("0x123".parse::<CanId>().is_err());
    assert!("standard 0x800".parse::<CanId>().is_err());

    Ok(())
}
