//! Cohort management operations on `TidalDb`.

use crate::cohort::serialize_cohort_def;
use crate::schema::EntityId;
use crate::storage::{Tag, encode_key};

use super::TidalDb;

impl TidalDb {
    /// Register a cohort definition.
    ///
    /// Persists the definition to durable storage (fjall) so it survives
    /// restarts. In ephemeral mode, the definition is only held in memory.
    ///
    /// # Errors
    ///
    /// Returns `TidalError::Internal` if a cohort with the same name already exists.
    pub fn define_cohort(&self, def: crate::cohort::CohortDef) -> crate::Result<()> {
        self.require_writeable("define_cohort")?;
        // Persist to durable storage before registering in-memory, so a crash
        // between the two leaves the definition on disk for the next open.
        if let Some(ref storage) = self.storage {
            let key = encode_key(EntityId::new(0), Tag::CohortDef, def.name.as_bytes());
            let value = serialize_cohort_def(&def);
            if let Err(e) = storage.items_engine().put(&key, &value) {
                tracing::warn!(
                    error = %e,
                    name = %def.name,
                    "failed to persist cohort definition"
                );
            }
        }

        self.cohort_registry.define(def)
    }
}
