//! Inventory record for one statically-registered operation.

use crate::context::OpContext;
use crate::error::OpError;
use crate::output::OpOutput;

/// Bare-fn pointer signature for ops registered via inventory.
/// `#[onto_operation]` emits one entry per annotated function and
/// stores a pointer of this type in the registry.
pub type OpFn = fn(inputs: &serde_json::Value, ctx: &mut OpContext) -> Result<OpOutput, OpError>;

/// Link-time record emitted by `#[onto_operation]`. Aggregated via
/// `inventory::collect!(OperationEntry)` (see `lib.rs`).
#[derive(Debug)]
pub struct OperationEntry {
    /// Canonical id — matches `catalog/operations/<id>.ncl::id`.
    pub id: &'static str,
    /// One-line description. Surfaces to MCP/CLI/HTTP catalog responses.
    pub description: &'static str,
    /// Validation SLA tag: `"Synchronous"`, `"EventualWithin"`, or
    /// `"Background"`. Parsed by the runtime when assembling the
    /// pipeline.
    pub validation_sla: &'static str,
    /// Free-form precondition slice description (e.g. a slice query id).
    /// The runtime interprets this with the precondition loader for
    /// the op's domain.
    pub precondition: &'static str,
    /// Pre-validators invoked before the op body. Any non-Accept verdict
    /// aborts the pipeline with [`crate::OpError::ValidatorRejected`].
    pub pre_validators: &'static [&'static str],
    /// Inline validators — callable from inside the op body via
    /// [`crate::validation::dispatch::dispatch`]. The runtime does NOT
    /// invoke these; they exist in the registry for declarative parity
    /// with the catalog NCL.
    pub inline_validators: &'static [&'static str],
    /// Post-validators invoked after the op body. Currently always
    /// synchronous; async post-validation per `validation_sla` arrives
    /// alongside `AttestationOp` (ADR-026 / D14).
    pub post_validators: &'static [&'static str],
    /// Roles permitted to invoke the op. Empty = no role gating.
    pub actor_policy: &'static [&'static str],
    /// Effect specs in `"Kind:Entity:Attrs:Dimension"` form, one per
    /// effect declared. Parsed by the runtime when applying the op.
    pub effects: &'static [&'static str],
    /// NCL files regenerated from authoritative state after apply.
    pub render_paths: &'static [&'static str],
    /// Witness payload kind (`"state_transition"`, `"node_upsert"`, …).
    pub witness_shape: &'static str,
    /// Optional CRDT strategy tag — empty when single-writer.
    pub crdt_strategy: &'static str,
    /// Feature flag required at runtime (empty = always available).
    pub feature: &'static str,
    /// `file!()` at the point of registration — useful for diagnostics.
    pub source_file: &'static str,
    /// Function pointer for execution. The `#[onto_operation]` macro
    /// captures the annotated function and emits a reference to it
    /// here so dispatch can call it.
    pub execute: OpFn,
}

inventory::collect!(OperationEntry);
