//! Versioned host capabilities available to WebAssembly Components.

mod clock;
mod kv;
mod registry;

pub use kv::{KV_MAX_KEY_BYTES, KV_MAX_VALUE_BYTES, KvBackend, KvBackendError};
pub use registry::CapabilityDescriptor;
pub(crate) use registry::{Capability, CapabilityRegistry};

/// Per-Actor state owned by enabled host capabilities.
pub(crate) struct HostCapabilities {
    clock: Option<clock::ClockState>,
    kv: Option<kv::KvState>,
}

impl HostCapabilities {
    pub(crate) fn new(
        capabilities: &[Capability],
        service_id: &str,
        kv_backend: Option<std::sync::Arc<dyn KvBackend>>,
        deadline: std::time::Duration,
    ) -> Self {
        Self {
            clock: capabilities
                .contains(&Capability::MonotonicClock)
                .then(clock::ClockState::new),
            kv: capabilities.contains(&Capability::KvStore).then(|| {
                kv::KvState::new(
                    service_id,
                    kv_backend.expect("KV Components are rejected when no backend is configured"),
                    deadline,
                )
            }),
        }
    }

    fn monotonic_clock_now(&self) -> u64 {
        self.clock
            .as_ref()
            .expect("the Clock interface is linked only when its state is enabled")
            .now()
    }

    fn kv(&self) -> &kv::KvState {
        self.kv
            .as_ref()
            .expect("the KV interface is linked only when its state is enabled")
    }
}
