nautalid 0.1.0

Scratch container substrate — TLS 1.3 HTTP/2+3 kernel, LID/AetherDB, optional filter bus (GPL-3.0-or-later).
//! Crate embedding — programmatic backend configuration (not env-only).
//!
//! Binary entrypoints use [`EmbedConfig::from_env`]; library consumers build
//! [`EmbedConfig`] (or [`EmbedBuilder`]) and call [`install_subsystems`] after
//! assembling [`crate::state::AppState`].

use std::sync::Arc;

use crate::state::AppState;

#[cfg(feature = "kwt")]
use crate::kwt_replay::AetherRuntime;
#[cfg(feature = "kwt")]
use crate::wt_aether::WtAetherConfig;

/// Programmatic subsystem toggles for Nautalid-as-a-library.
#[derive(Debug, Clone)]
pub struct EmbedConfig {
    /// Enable HTTP/3 WebTransport session handling (also settable via `NAUTALID_WEBTRANSPORT=1`).
    pub webtransport: bool,
    /// WebTransport ↔ AetherDB bridge policy (`None` = off unless env enables aether).
    #[cfg(feature = "kwt")]
    pub wt_aether: Option<WtAetherConfig>,
}

impl Default for EmbedConfig {
    fn default() -> Self {
        Self {
            webtransport: false,
            #[cfg(feature = "kwt")]
            wt_aether: None,
        }
    }
}

impl EmbedConfig {
    /// Mirror binary/container env for WebTransport and WT ↔ Aether routing.
    #[must_use]
    pub fn from_env() -> Self {
        let webtransport = crate::webtransport::enabled_from_env();
        #[cfg(feature = "kwt")]
        let wt_aether = if webtransport || crate::surfaces::env_enabled("NAUTALID_WEBTRANSPORT_AETHER")
        {
            Some(WtAetherConfig::from_env())
        } else {
            None
        };
        Self {
            webtransport,
            #[cfg(feature = "kwt")]
            wt_aether,
        }
    }
}

/// Fluent builder for [`EmbedConfig`].
#[derive(Debug, Default)]
pub struct EmbedBuilder {
    config: EmbedConfig,
}

impl EmbedBuilder {
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    #[must_use]
    pub fn from_env() -> Self {
        Self {
            config: EmbedConfig::from_env(),
        }
    }

    #[must_use]
    pub fn webtransport(mut self, enabled: bool) -> Self {
        self.config.webtransport = enabled;
        self
    }

    #[cfg(feature = "kwt")]
    #[must_use]
    pub fn wt_aether(mut self, config: WtAetherConfig) -> Self {
        self.config.wt_aether = Some(config);
        self
    }

    #[must_use]
    pub fn build(self) -> EmbedConfig {
        self.config
    }
}

/// Wire optional backends after manual [`AppState`] assembly.
pub fn install_subsystems(state: &AppState, config: &EmbedConfig) {
    crate::webtransport::set_enabled(config.webtransport);

    #[cfg(feature = "kwt")]
    if let Some(runtime) = &state.aether_runtime {
        if let Some(wt) = &config.wt_aether {
            #[cfg(feature = "filter")]
            crate::wt_aether::install_with_filter(
                Arc::clone(runtime),
                wt.clone(),
                Some(state.filter.clone()),
            );
            #[cfg(not(feature = "filter"))]
            crate::wt_aether::install(Arc::clone(runtime), wt.clone());
        } else if config.webtransport {
            #[cfg(feature = "filter")]
            crate::wt_aether::install_with_filter(
                Arc::clone(runtime),
                WtAetherConfig::from_env(),
                Some(state.filter.clone()),
            );
            #[cfg(not(feature = "filter"))]
            crate::wt_aether::install(
                Arc::clone(runtime),
                WtAetherConfig::from_env(),
            );
        }
        runtime.ensure_wire_pool();
    }

    let _ = state;
}

/// Env-driven install (binary default).
pub fn install_subsystems_from_env(state: &AppState) {
    install_subsystems(state, &EmbedConfig::from_env());
}

#[cfg(feature = "kwt")]
/// Assemble a minimal LID-enabled [`AppState`] for crate embedding.
pub fn state_with_runtime(
    runtime: Arc<AetherRuntime>,
    kwt: crate::kwt_access::KwtAccessConfig,
) -> AppState {
    AppState::new(
        #[cfg(feature = "image-trust")]
        None,
        Some(kwt),
        Some(runtime),
        #[cfg(feature = "filter")]
        crate::filter::FilterStore::default(),
    )
}