//! Ratchets — announce-time forward secrecy (`ARCHITECTURE.md` §3.9).
//!
//! Ratchets are short-lived X25519 keys announced by destinations. A sender
//! encrypts to the latest known ratchet public key instead of the static
//! encryption key; receivers keep a window of recent ratchet private keys so
//! in-flight packets still decrypt after a rotation.

use std::collections::HashMap;
use std::time::Instant;

use rand_core::CryptoRngCore;

use plexus_core::AddressHash;

/// A ratchet public key with its creation time.
#[derive(Debug, Clone, Copy)]
pub struct Ratchet {
    /// Ratchet identifier (hash of the public key).
    pub id: [u8; 32],
    /// When it was created.
    pub created_at: Instant,
}

/// A private ratchet key we hold for a destination we own.
pub struct RatchetPriv {
    secret: [u8; 32],
    created_at: Instant,
}

/// The latest-known public ratchet for a destination we know.
#[derive(Debug, Clone, Copy)]
pub struct RatchetPub {
    /// The ratchet public key.
    pub public: [u8; 32],
    /// When it was announced/created.
    pub created_at: Instant,
}

/// Store of owned and known ratchets (§3.9).
#[derive(Default)]
pub struct RatchetStore {
    /// For destinations we own: our active and recently-active private ratchets.
    owned: HashMap<AddressHash, Vec<RatchetPriv>>,
    /// For destinations we know: the latest public ratchet they announced.
    known: HashMap<AddressHash, RatchetPub>,
}

impl RatchetStore {
    /// Reference policy: keep ratchets for 30 days (`RATCHET_EXPIRY`). Returns
    /// the number evicted.
    pub fn evict_expired(&mut self, now: Instant) -> usize {
        todo!()
    }

    /// The latest known public ratchet for a destination.
    pub fn latest_for(&self, dst: &AddressHash) -> Option<&RatchetPub> {
        todo!()
    }

    /// Rotate our owned ratchet for a destination we own.
    pub fn rotate_owned(&mut self, dst: &AddressHash, rng: &mut impl CryptoRngCore) {
        todo!()
    }

    /// Remember a ratchet announced by a destination we know.
    pub fn remember_announced(&mut self, dst: AddressHash, ratchet: RatchetPub) {
        todo!()
    }
}
