//! Format v2 invariants: VERSION_BYTE = 0x02, v1 blobs are rejected with
//! UnsupportedFormatVersion, length-prefix construction guarantees domain
//! separation.

use relicario_core::{
    RelicarioError,
    crypto::{KdfParams, VERSION_BYTE},
    decrypt, derive_master_key, encrypt,
};
use zeroize::Zeroizing;

fn fast_params() -> KdfParams { KdfParams { argon2_m: 256, argon2_t: 1, argon2_p: 1 } }

#[test]
fn version_byte_is_2() {
    assert_eq!(VERSION_BYTE, 0x02);
}

#[test]
fn fresh_ciphertext_starts_with_0x02() {
    let key = Zeroizing::new([0u8; 32]);
    // encrypt(key: &[u8; 32], plaintext: &[u8])
    let ct = encrypt(&key, b"hello").unwrap();
    assert_eq!(ct[0], 0x02);
}

#[test]
fn v1_blob_is_rejected_with_unsupported_format_version() {
    // v1 layout: [0x01][24 nonce bytes][16 tag bytes]
    let mut blob = vec![0x01u8];
    blob.extend_from_slice(&[0u8; 24 + 16]);
    let key = Zeroizing::new([0u8; 32]);
    // decrypt(key: &[u8; 32], data: &[u8])
    let err = decrypt(&key, &blob);
    match err {
        Err(RelicarioError::UnsupportedFormatVersion { found, expected }) => {
            assert_eq!(found, 0x01);
            assert_eq!(expected, 0x02);
        }
        other => panic!("expected UnsupportedFormatVersion, got {other:?}"),
    }
}

#[test]
fn length_prefix_distinguishes_concat_collisions() {
    let salt = [0u8; 32];
    let img = [0x44u8; 32];
    let p1 = b"abc";
    let p2 = b"abcD";  // Pre-length-prefix, ("abc", [0x44, ...]) and ("abcD", ...)
                       // could be made to collide. With length-prefix they cannot.
    let k1 = derive_master_key(p1, &img, &salt, &fast_params()).unwrap();
    let k2 = derive_master_key(p2, &img, &salt, &fast_params()).unwrap();
    assert_ne!(*k1, *k2);
}
