/*
    Appellation: actor <module>
    Contrib: @FL03
*/
use crate::ctx::ActorContext;
use crate::drivers::RawDriver;
use crate::mem::TopoLedger;
use rshyper::EdgeId;
use rstmt::nrt::{LPR, Triad};

/// Actors represent different operational modes that a virtual node can adopt,
/// each providing specialized behavior patterns and capabilities.
pub trait Actor<D, T>
where
    D: RawDriver<Triad>,
{
    /// Returns the name of this actor type
    fn kind(&self) -> &'static str;

    /// Initialize the actor with required resources
    fn initialize(&mut self) -> crate::Result<()>;

    /// Process a transformation request and determine response
    fn process_transform(
        &mut self,
        transform: LPR,
        driver: &mut D,
        memory: &mut TopoLedger<T>,
    ) -> crate::Result<bool>;

    /// Process incoming message from another node
    fn process_message(
        &mut self,
        source: EdgeId,
        message: &[u8],
        memory: &mut TopoLedger<T>,
    ) -> crate::Result<()>;

    /// Called when the node enters this actor mode
    fn on_activate(&mut self, driver: &D, memory: &mut TopoLedger<T>) -> crate::Result<()>;

    /// Called when the node leaves this actor mode
    fn on_deactivate(&mut self, driver: &D, memory: &mut TopoLedger<T>) -> crate::Result<()>;

    /// Calculate resource requirements for this actor mode
    fn resource_requirements(&self) -> (usize, usize); // (memory, compute)

    /// Whether this actor allows pattern sharing
    fn allows_pattern_sharing(&self) -> bool;

    /// Derive contextual meaning from current state
    fn contextualize(&self, driver: &D, memory: &TopoLedger<T>) -> crate::Result<ActorContext<T>>;
}

pub trait ActorExt<D, T>: Actor<D, T>
where
    D: RawDriver<Triad>,
{
    /// Propose a transformation based on current state
    fn propose_transformation(&self, driver: &D, memory: &TopoLedger<T>) -> Option<LPR>;
}
