/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/

use crate::{Object, ObjectBuffer, fields};

fields! {
    NAME: &str = b"name";
    AGE: u32 = b"age1";
    FRIEND: &str = b"frnd";
    STUFF: Object = b"stff";
}

fn test_object() -> ObjectBuffer {
    ObjectBuffer::new(&mut [
        (NAME.0, &"Bob"),
        (AGE.0, &35_u32),
        (FRIEND.0, &"Alice"),
        (FRIEND.0, &"Charlie"),
    ])
}

#[test]
fn read_single_field() {
    let bob = test_object();
    let bob = bob.as_object();
    assert_eq!(bob.get(NAME), Some("Bob"));
    assert_eq!(bob.get(AGE), Some(35));
}

#[test]
fn read_multi_field() {
    let bob = test_object();
    let bob = bob.as_object();

    let mut friends = bob.iter(FRIEND);
    assert_eq!(friends.next(), Some("Alice"));
    assert_eq!(friends.next(), Some("Charlie"));
    assert_eq!(friends.next(), None);
}

#[test]
fn vec_align_test() {
    let mut c = 0;
    for _ in 0..10_000 {
        let x = Vec::<u8>::with_capacity(16);
        if x.as_ptr().align_offset(4) == 0 {
            c += 1;
        }
    }
    assert_eq!(c, 10_000, "correctly aligned vecs by system allocator")
}

#[test]
fn insert() {
    let bob = test_object();
    let edward = bob.as_object().insert(NAME, "Edward");

    eprintln!("{:#?}", bob.as_object());
    let edward = edward.as_object();
    eprintln!("{edward:#?}");
    assert_eq!(edward.get(NAME), Some("Edward"));
    assert_eq!(edward.get(AGE), Some(35));

    let mut friends = edward.iter(FRIEND);
    assert_eq!(friends.next(), Some("Alice"));
    assert_eq!(friends.next(), Some("Charlie"));
    assert_eq!(friends.next(), None);
}

#[test]
fn insert_empty() {
    let ob = Object::EMPTY.insert(NAME, "Romeo");
    assert_eq!(ob.as_object().get(NAME), Some("Romeo"));

    let ob = Object::EMPTY.insert(STUFF, Object::EMPTY);
    assert_eq!(ob.as_object().get(STUFF), Some(Object::EMPTY));
}

#[test]
fn debug() {
    assert_eq!(
        format!("{:?}", test_object()),
        "Object { age1: 35, frnd: \"Alice\", frnd: \"Charlie\", name: \"Bob\" }"
    );
}
