//! [`Cache`] port — best-effort `sv:{sub}` cache.

use std::time::Duration;

use async_trait::async_trait;

/// Best-effort cache of `sv:{sub}` values.
///
/// Promoted to the SDK in Phase 11.Z from chat-auth's private
/// `SessionVersionCache` trait (§3 Row 6 "replace, don't layer"). The
/// shape is identical: `get` returns `None` on miss OR transient cache
/// error; the [`super::CompositeEpochRevocation`] composer falls
/// through to its [`super::Fetcher`] in either case, so `Cache` impls
/// don't expose error variants. `set` is best-effort and swallows
/// failures internally — a failed write only means the next call will
/// fetch again.
///
/// `key` is the full `sv:{sub}` form (built via
/// [`super::sv_cache_key`]) so the SDK port matches the canonical
/// PAS↔consumer shared-cache contract documented in
/// `STANDARDS_SHARED_CACHE.md` §3.1.
///
/// ## Implementations
///
/// - [`super::InProcessTtlCache`] — opinionated per-pod TTL map; default
///   wiring for RCW/CTW (Slice 4/5).
/// - chat-auth-internal — KVRocks-backed reader (kept consumer-side
///   because it depends on `ppoppo-kvrocks`, which is not in the SDK
///   feature graph).
/// - 11.AB+ — SDK ships a KVRocks-backed `Cache` once
///   `KVROCKS_URL` ACL extends to RCW/CTW.
#[async_trait]
pub trait Cache: Send + Sync {
    /// Look up the cached `sv` for `key` (`"sv:{sub}"`).
    ///
    /// Returns `None` on miss OR transient cache error — the composer
    /// treats both identically (fall through to the authoritative
    /// fetcher), so callers don't need separate error handling for
    /// cache unavailability.
    async fn get(&self, key: &str) -> Option<i64>;

    /// Best-effort write-back after a successful fetch. Implementations
    /// SHOULD honor the `ttl` (Redis `SETEX`, KVRocks TTL, in-process
    /// expiration). Failures are swallowed — the next call will fetch
    /// again.
    async fn set(&self, key: &str, sv: i64, ttl: Duration);
}
