use crate::audit::AuditLog;
use crate::bus::CommandBus;
use crate::command::CommandRegistry;
use crate::context::RuntimeContext;
use crate::decision::{DecisionEngine, DecisionOutcome, DecisionRegistry};
use crate::envelope::CommandEnvelope;
use crate::error::RuntimeResult;
use crate::event::EventRegistry;
use crate::event_bus::EventBus;
use crate::handler::CommandResult;
use crate::identity::RuntimeIdentity;
use crate::lifecycle::RuntimeLifecycle;
use crate::state::StateRegistry;
use appcore_contracts::ApplicationManifestV1;
#[derive(Debug)]
pub struct RuntimeInstance {
pub(crate) application_manifest: ApplicationManifestV1,
pub(crate) identity: RuntimeIdentity,
pub(crate) command_registry: CommandRegistry,
pub(crate) event_registry: EventRegistry,
pub(crate) state_registry: StateRegistry,
pub(crate) decision_registry: DecisionRegistry,
pub(crate) decision_engine: DecisionEngine,
pub(crate) command_bus: CommandBus,
pub(crate) event_bus: EventBus,
pub(crate) audit_log: AuditLog,
pub(crate) lifecycle: RuntimeLifecycle,
}
impl RuntimeInstance {
pub fn application_manifest(&self) -> &ApplicationManifestV1 {
&self.application_manifest
}
pub fn identity(&self) -> &RuntimeIdentity {
&self.identity
}
pub fn commands(&self) -> &CommandRegistry {
&self.command_registry
}
pub fn events(&self) -> &EventRegistry {
&self.event_registry
}
pub fn states(&self) -> &StateRegistry {
&self.state_registry
}
pub fn decisions(&self) -> &DecisionRegistry {
&self.decision_registry
}
pub fn command_bus(&self) -> &CommandBus {
&self.command_bus
}
pub fn lifecycle(&self) -> &RuntimeLifecycle {
&self.lifecycle
}
pub fn event_bus(&self) -> &EventBus {
&self.event_bus
}
pub fn audit_log(&self) -> &AuditLog {
&self.audit_log
}
pub fn dispatch_command(
&self,
command: &CommandEnvelope,
context: &dyn RuntimeContext,
) -> RuntimeResult<CommandResult> {
match self.decision_engine.evaluate(command, context)? {
DecisionOutcome::Allow => self.command_bus.dispatch(command, context),
DecisionOutcome::Deny(message) => Ok(CommandResult::rejected(message)),
DecisionOutcome::Defer(message) => Ok(CommandResult::rejected(message)),
}
}
pub fn ensure_compatible(&self, other: &RuntimeIdentity) -> RuntimeResult<()> {
self.identity().ensure_compatible(other)
}
}