#![cfg(feature = "var-collections")]

use armdb::{Config, VarTree};
use tempfile::tempdir;

#[test]
fn test_compaction_var_tree() {
    let dir = tempdir().unwrap();
    let mut config = Config::test();
    config.max_file_size = 4096;
    config.write_buffer_size = 4096;
    config.compaction_threshold = 0.1;

    let tree = VarTree::<[u8; 8]>::open(dir.path(), config).unwrap();

    // Write some entries
    for i in 0..1000u64 {
        let key = i.to_be_bytes();
        tree.put(&key, &key).unwrap();
    }

    // Overwrite half of them
    for i in 0..500u64 {
        let key = i.to_be_bytes();
        let val = (i + 1).to_be_bytes();
        tree.put(&key, &val).unwrap();
    }

    println!("Tree len before compaction: {}", tree.len());

    // Check data BEFORE compaction
    for i in 0..1000u64 {
        let key = i.to_be_bytes();
        assert!(
            tree.get(&key).is_some(),
            "Key not found BEFORE compaction: {}",
            i
        );
    }

    // Trigger compaction
    let _compacted = tree.compact().unwrap();

    println!("Tree len after compaction: {}", tree.len());

    // Check data integrity
    for i in 0..1000u64 {
        let key = i.to_be_bytes();
        let expected = if i < 500 {
            (i + 1).to_be_bytes()
        } else {
            i.to_be_bytes()
        };
        let val = tree.get(&key).unwrap_or_else(|| {
            let mut keys = Vec::new();
            for k in tree.prefix_iter(&[]).collect_keys() {
                keys.push(u64::from_be_bytes(k));
            }
            keys.sort();
            panic!("Key not found: i={}. All keys: {:?}", i, keys);
        });
        assert_eq!(val.as_bytes(), &expected);
    }
}
