#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;

use asherah as ael;

#[test]
fn ik_cache_ttl_expires_and_reloads() {
    let crypto = Arc::new(ael::aead::AES256GCM::new());
    let kms = Arc::new(ael::kms::StaticKMS::new(crypto.clone(), vec![6_u8; 32]).unwrap());
    let store = Arc::new(ael::metastore::InMemoryMetastore::new());
    let mut cfg = ael::Config::new("svc", "prod");
    cfg.policy.shared_intermediate_key_cache = false;
    cfg.policy.cache_intermediate_keys = true;
    cfg.policy.revoke_check_interval_s = 1; // TTL
    let factory = ael::api::new_session_factory(cfg, store, kms, crypto);
    let sess = factory.get_session("p1");

    // First encrypt loads and caches IK
    let d1 = sess.encrypt(b"hello").unwrap();
    let ik1 = d1.key.unwrap().parent_key_meta.unwrap().created;

    // Immediately encrypt again - should hit cache (IK unchanged)
    let d2 = sess.encrypt(b"world").unwrap();
    let ik2 = d2.key.unwrap().parent_key_meta.unwrap().created;
    assert_eq!(ik1, ik2);

    // After TTL, encrypt again - IK may rotate due to expiration policy defaults; at least force reload
    sleep(Duration::from_millis(1100));
    let d3 = sess.encrypt(b"again").unwrap();
    let ik3 = d3.key.unwrap().parent_key_meta.unwrap().created;
    // Not strictly guaranteed to differ, but ensure not panicking and value is present
    assert!(ik3 >= ik2);
}
