use mldsa_native_rs::ffi;

mod common;

const SUCCESS: ffi::c_int = 0;
const FAILURE: ffi::c_int = -1;

#[test]
fn raw_ffi_mldsa44_detached_sign_and_verify_roundtrip() {
    let mut pk = [0u8; ffi::MLDSA44_PUBLICKEYBYTES as usize];
    let mut sk = [0u8; ffi::MLDSA44_SECRETKEYBYTES as usize];
    let mut sig = [0u8; ffi::MLDSA44_BYTES as usize];

    let msg: &[u8] = &[1, 2, 3, 4, 5];

    let res = unsafe { ffi::mldsa44_keypair(pk.as_mut_ptr(), sk.as_mut_ptr()) };
    assert_eq!(res, SUCCESS);

    let mut sig_output_len: usize = 0;
    let res = unsafe {
        ffi::mldsa44_signature(
            sig.as_mut_ptr(),
            &mut sig_output_len as *mut usize,
            msg.as_ptr(),
            msg.len(),
            std::ptr::null(),
            0,
            sk.as_ptr(),
        )
    };
    assert_eq!(res, SUCCESS);
    assert_eq!(sig_output_len, ffi::MLDSA44_BYTES as usize);

    let res = unsafe {
        ffi::mldsa44_verify(
            sig.as_ptr(),
            sig_output_len,
            msg.as_ptr(),
            msg.len(),
            std::ptr::null(),
            0,
            pk.as_ptr(),
        )
    };
    assert_eq!(res, SUCCESS);
}

#[test]
fn raw_ffi_mldsa44_detached_sign_and_verify_roundtrip_tampered_msg() {
    let mut pk = [0u8; ffi::MLDSA44_PUBLICKEYBYTES as usize];
    let mut sk = [0u8; ffi::MLDSA44_SECRETKEYBYTES as usize];
    let mut sig = [0u8; ffi::MLDSA44_BYTES as usize];

    let msg: &[u8] = &[1, 2, 3, 4, 5];

    let res = unsafe { ffi::mldsa44_keypair(pk.as_mut_ptr(), sk.as_mut_ptr()) };
    assert_eq!(res, SUCCESS);

    let mut sig_output_len: usize = 0;
    let res = unsafe {
        ffi::mldsa44_signature(
            sig.as_mut_ptr(),
            &mut sig_output_len as *mut usize,
            msg.as_ptr(),
            msg.len(),
            std::ptr::null(),
            0,
            sk.as_ptr(),
        )
    };
    assert_eq!(res, SUCCESS);
    assert_eq!(sig_output_len, ffi::MLDSA44_BYTES as usize);

    let other_msg: &[u8] = &[3, 2, 3, 4, 5];
    let res = unsafe {
        ffi::mldsa44_verify(
            sig.as_ptr(),
            sig_output_len,
            other_msg.as_ptr(),
            other_msg.len(),
            std::ptr::null(),
            0,
            pk.as_ptr(),
        )
    };
    assert_eq!(res, FAILURE);
}
