use std::collections::{HashMap, HashSet};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::Result;
use crate::graph::command::NodeResult;
use crate::graph::reducer::StateReducer;
use crate::harness::ids::{GraphId, NodeId, RunId, ThreadId};
pub const START: &str = "__start__";
pub const END: &str = "__end__";
pub type NodeFuture<Update> = Pin<Box<dyn Future<Output = Result<NodeResult<Update>>> + Send>>;
pub type NodeHandler<State, Update> =
dyn Fn(State, NodeContext) -> NodeFuture<Update> + Send + Sync;
pub type RouterFn<State> = dyn Fn(&State) -> String + Send + Sync;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ForkId {
pub branch_index: usize,
pub node: NodeId,
}
impl ForkId {
pub fn new(branch_index: usize, node: NodeId) -> Self {
Self { branch_index, node }
}
}
#[derive(Clone, Debug)]
pub struct NodeContext {
pub node_id: NodeId,
pub run_id: RunId,
pub thread_id: Option<ThreadId>,
pub step: usize,
pub resume: Option<serde_json::Value>,
pub fork: Option<ForkId>,
}
pub(crate) struct BuilderNode<State, Update> {
#[allow(dead_code)]
pub(crate) id: NodeId,
pub(crate) handler: Arc<NodeHandler<State, Update>>,
}
impl<State, Update> Clone for BuilderNode<State, Update> {
fn clone(&self) -> Self {
Self {
id: self.id.clone(),
handler: self.handler.clone(),
}
}
}
pub(crate) struct Branch<State> {
pub(crate) router: Arc<RouterFn<State>>,
pub(crate) routes: HashMap<String, NodeId>,
}
impl<State> Clone for Branch<State> {
fn clone(&self) -> Self {
Self {
router: self.router.clone(),
routes: self.routes.clone(),
}
}
}
pub struct GraphBuilder<State, Update> {
pub(crate) graph_id: GraphId,
pub(crate) nodes: HashMap<NodeId, BuilderNode<State, Update>>,
pub(crate) edges: HashMap<NodeId, NodeId>,
pub(crate) branches: HashMap<NodeId, Branch<State>>,
pub(crate) command_nodes: HashSet<NodeId>,
pub(crate) reducer: Option<Arc<dyn StateReducer<State, Update>>>,
pub(crate) recursion_limit: usize,
pub(crate) parallel: bool,
}