use second_brain_core::{
    kuzu_store::KuzuStore,
    schema::{Memory, MemoryType},
    store::Store,
};

#[test]
fn record_access_adds_no_log_row() {
    let store = KuzuStore::in_memory("test-machine-access".to_string()).unwrap();
    let memory = Memory::new(
        "access bump test".to_string(),
        MemoryType::Semantic,
        "test".to_string(),
        String::new(),
    );
    store.store_memory(&memory).unwrap();

    let entries_after_store = store.sync_log_since(0).unwrap();
    assert_eq!(
        entries_after_store.len(),
        1,
        "store_memory must produce exactly one SyncLog row"
    );

    for _ in 0..3 {
        let mut m = memory.clone();
        m.reinforce();
        store.record_access(&m).unwrap();
    }

    let entries_after_access = store.sync_log_since(0).unwrap();
    assert_eq!(
        entries_after_access.len(),
        1,
        "record_access must not append any SyncLog rows"
    );
}

#[test]
fn write_creates_node_and_log_row() {
    let store = KuzuStore::in_memory("test-machine".to_string()).unwrap();
    let memory = Memory::new(
        "sync log test".to_string(),
        MemoryType::Semantic,
        "test".to_string(),
        String::new(),
    );
    store.store_memory(&memory).unwrap();

    let machine_id = store.machine_id().to_string();
    let entries = store.sync_log_since(0).unwrap();
    assert_eq!(entries.len(), 1, "expected exactly one SyncLog row");

    let entry = &entries[0];
    assert_eq!(entry.origin_machine_id, machine_id);
    assert_eq!(entry.local_seq, entry.origin_seq);
    let expected_id = format!("{}:{}", machine_id, entry.origin_seq);
    assert_eq!(entry.id, expected_id);

    let mem_count = store.memory_count().unwrap();
    assert_eq!(mem_count, 1, "expected exactly one Memory node");
}

#[test]
fn sequential_writes_increment_local_seq() {
    let store = KuzuStore::in_memory("test-machine-seq".to_string()).unwrap();

    let m1 = Memory::new(
        "first memory".to_string(),
        MemoryType::Semantic,
        "test".to_string(),
        String::new(),
    );
    let m2 = Memory::new(
        "second memory".to_string(),
        MemoryType::Semantic,
        "test".to_string(),
        String::new(),
    );

    store.store_memory(&m1).unwrap();
    store.store_memory(&m2).unwrap();

    let entries = store.sync_log_since(0).unwrap();
    assert_eq!(entries.len(), 2, "expected two SyncLog rows");

    let seq1 = entries[0].local_seq;
    let seq2 = entries[1].local_seq;
    assert_eq!(
        seq2,
        seq1 + 1,
        "local_seq values must be consecutive with no gap"
    );
}
