//! Scheduled actions with helper functions
use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc;

use generational_arena::Index;
use generational_indextree::NodeId as TreeIndex;

use phreak_facts::FactCore;

pub(crate) type ClassNodeId = String;
pub(crate) type AlphaNodeId = Index;
pub(crate) type BetaNodeId = TreeIndex;
pub(crate) type SegmentId = TreeIndex;
pub(crate) type TokenId = TreeIndex;

/// A scheduled action on a node
#[derive(Clone)]
pub(crate) enum ScheduledAction {
    /// A fact has been inserted into the linked alphamemory
    FactInserted(Rc<FactCore>),
    /// A fact has been removed from the linked alphamemory
    FactRemoved(Rc<FactCore>),
    /// A token has been inserted into the parent betanode and might result in matches
    ParentTokenInserted(TokenId),
    /// A token has been removed from the parent betanode and might result in matches
    ParentTokenRemoved(TokenId),
    /// A match was made in a join node, and needs to be inserted into the memory or production node
    InsertToken(TokenId),
    /// An existing token in a NCC became empty and will activate
    ActivateToken(TokenId),
    /// parent_id, sub_id -> deletes all ancestors from sub_id upto and including it's parent_id
    DeleteTokenChain(TokenId, TokenId),
    /// delete all child tokens from the given token_id, but not the token_id itself
    DeleteChildTokens(TokenId),
}

impl Debug for ScheduledAction {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        match self {
            ScheduledAction::FactInserted(rc) => {
                write!(f, "FactInserted({},{},{})", &*rc.0, &*rc.1, &*rc.2)
            }
            ScheduledAction::FactRemoved(rc) => {
                write!(f, "FactRemoved({},{},{})", &*rc.0, &*rc.1, &*rc.2)
            }
            ScheduledAction::ParentTokenInserted(id) => {
                write!(f, "ParentTokenInserted({:?})", id)
            }
            ScheduledAction::ParentTokenRemoved(id) => {
                write!(f, "ParentTokenRemoved({:?})", id)
            }
            ScheduledAction::InsertToken(id) => {
                write!(f, "InsertToken({:?})", id)
            }
            ScheduledAction::DeleteTokenChain(parent, id) => {
                write!(f, "DeleteTokenChain({:?}, {:?})", parent, id)
            }
            ScheduledAction::DeleteChildTokens(id) => {
                write!(f, "DeleteChildTokens({:?})", id)
            }
            ScheduledAction::ActivateToken(id) => {
                write!(f, "ActivateToken({:?})", id)
            }
        }
    }
}
