use crate::raft::client::RaftClient;
use std::any::Any;
use std::sync::Arc;

pub enum Storage {
    MEMORY,
    DISK(String),
}

#[derive(Debug)]
pub enum OpType {
    COMMAND,
    QUERY,
    SUBSCRIBE,
}

pub trait StateMachineCtl: Sync + Send + Any {
    fn id(&self) -> u64;
    fn snapshot(&self) -> Option<Vec<u8>>;
    fn recover(&mut self, data: Vec<u8>) -> ::futures::future::BoxFuture<()>;
    fn fn_dispatch_qry<'a>(
        &'a self,
        fn_id: u64,
        data: &'a Vec<u8>,
    ) -> ::futures::future::BoxFuture<'a, Option<Vec<u8>>>;
    fn fn_dispatch_cmd<'a>(
        &'a mut self,
        fn_id: u64,
        data: &'a Vec<u8>,
    ) -> ::futures::future::BoxFuture<'a, Option<Vec<u8>>>;
    fn op_type(&mut self, fn_id: u64) -> Option<OpType>;
}

pub trait OpTypes {
    fn op_type(&self, fn_id: u64) -> Option<OpType>;
}

pub trait StateMachineClient {
    fn new_instance(sm_id: u64, client: &Arc<RaftClient>) -> Self;
}

#[macro_use]
pub mod macros;
pub mod callback;
pub mod configs;
pub mod master;
