use crate::{RecallMessage, RecallStore, SessionMeta};
use std::sync::Arc;
pub async fn recall_contract(store: Arc<dyn RecallStore>) {
store.ensure_session("alice", "s1", &SessionMeta::new("s1", 100)).await.unwrap();
store.append("alice", "s1", &RecallMessage::new("user", "refactor the auth module today", 100)).await.unwrap();
store.append("alice", "s1", &RecallMessage::new("assistant", "starting the auth refactor now", 101)).await.unwrap();
store.append("alice", "s1", &RecallMessage::new("tool", "edited auth.rs", 102).with_tool_name("edit")).await.unwrap();
let hits = store.search("alice", "auth refactor", 5).await.unwrap();
assert_eq!(hits.len(), 1, "search should find the session");
assert_eq!(hits[0].session.session_id, "s1");
assert!(!hits[0].bookend_start.is_empty(), "hit carries bookends");
let scrolled = store.scroll("alice", "s1", 2, 1).await.unwrap();
assert!(scrolled.iter().all(|m| (m.id - 2).abs() <= 1));
assert!(scrolled.iter().any(|m| m.id == 2));
store.ensure_session("alice", "s2", &SessionMeta::new("s2", 200)).await.unwrap();
store.append("alice", "s2", &RecallMessage::new("user", "a newer session", 200)).await.unwrap();
let recent = store.recent("alice", 10).await.unwrap();
assert_eq!(recent.len(), 2);
assert_eq!(recent[0].session_id, "s2", "newest first");
let bob_search = store.search("bob", "auth refactor", 5).await.unwrap();
assert!(bob_search.is_empty(), "bob must not see alice's sessions");
let bob_recent = store.recent("bob", 10).await.unwrap();
assert!(bob_recent.is_empty(), "bob has no sessions");
let bob_scroll = store.scroll("bob", "s1", 1, 5).await.unwrap();
assert!(bob_scroll.is_empty(), "bob cannot scroll alice's session");
let empty = store.search("alice", "", 5).await.unwrap();
assert!(empty.is_empty());
}