// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

#[cfg(test)]
use super::Nonce;

#[test]
fn test_nonce_creation_from_string() {
    let nonce = Nonce::from("test_string");
    assert_eq!(nonce.as_bytes().len(), 32);
}

#[test]
fn test_nonce_creation_from_bytes() {
    let bytes = [1, 2, 3, 4];
    let nonce = Nonce::from(&bytes);
    assert_eq!(nonce.as_bytes().len(), 32);
    // First 4 bytes should match input, rest should be zeros
    assert_eq!(nonce.as_bytes()[0], 1);
    assert_eq!(nonce.as_bytes()[1], 2);
    assert_eq!(nonce.as_bytes()[2], 3);
    assert_eq!(nonce.as_bytes()[3], 4);
    assert_eq!(nonce.as_bytes()[4], 0);
}

#[test]
fn test_nonce_creation_from_u64() {
    let nonce = Nonce::from(12345u64);
    assert_eq!(nonce.as_bytes().len(), 32);
    // Should contain the little-endian representation of 12345
    let expected_bytes = 12345u64.to_le_bytes();
    for (i, &byte) in expected_bytes.iter().enumerate() {
        assert_eq!(nonce.as_bytes()[i], byte);
    }
    // Remaining bytes should be zeros
    for i in 8..32 {
        assert_eq!(nonce.as_bytes()[i], 0);
    }
}

#[test]
fn test_nonce_creation_from_large_array() {
    let large_bytes = [1u8; 64];
    let nonce = Nonce::from(&large_bytes);
    assert_eq!(nonce.as_bytes().len(), 32);
    // Should be hashed, so won't match input directly
}

#[test]
fn test_nonce_creation_from_vec_slice() {
    let vec_bytes = vec![5u8, 6u8, 7u8, 8u8];
    let nonce = Nonce::from(vec_bytes.as_slice());
    assert_eq!(nonce.as_bytes().len(), 32);
    // First 4 bytes should match input, rest should be zeros
    assert_eq!(nonce.as_bytes()[0], 5);
    assert_eq!(nonce.as_bytes()[1], 6);
    assert_eq!(nonce.as_bytes()[2], 7);
    assert_eq!(nonce.as_bytes()[3], 8);
    assert_eq!(nonce.as_bytes()[4], 0);
}

#[test]
fn test_nonce_creation_from_empty_slice() {
    let empty: &[u8] = &[];
    let nonce = Nonce::from(empty);
    assert_eq!(nonce.as_bytes().len(), 32);
    // All bytes should be zero
    assert!(nonce.as_bytes().iter().all(|&b| b == 0));
}

#[test]
fn test_nonce_display() {
    let nonce = Nonce::from([1u8; 32]);
    let hex_string = nonce.to_string();
    assert_eq!(hex_string.len(), 64); // 32 bytes * 2 hex chars per byte
    assert_eq!(
        hex_string,
        "0101010101010101010101010101010101010101010101010101010101010101"
    );
}

#[test]
fn test_nonce_equality() {
    let nonce1 = Nonce::from("test");
    let nonce2 = Nonce::from("test");
    let nonce3 = Nonce::from("different");

    assert_eq!(nonce1, nonce2);
    assert_ne!(nonce1, nonce3);
}

#[test]
fn test_nonce_new_direct() {
    let bytes = [42u8; 32];
    let nonce = Nonce::new(bytes);
    assert_eq!(nonce.as_bytes(), &bytes);
}

#[test]
fn test_nonce_from_short_str_const() {
    let nonce = Nonce::from_short_str("test");
    let from_from = Nonce::from("test");
    assert_eq!(nonce, from_from);

    // Test with exactly 32 bytes
    let s32 = "12345678901234567890123456789012";
    let nonce32 = Nonce::from_short_str(s32);
    let from_from32 = Nonce::from(s32);
    assert_eq!(nonce32, from_from32);
}
