use std::any::{Any, TypeId};
use std::sync::Arc;
use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::UserId;
use crate::actors::noise::Noise;
use crate::connection::NoiseFSM;
use crate::types::{
AdminRequest, ClientInfo, CoreBrokerConnect, CoreBrokerConnectResponse, CoreMessage,
CoreMessageV0, CoreResponse, CoreResponseContentV0, CoreResponseV0, ExtResponse,
};
use crate::{actor::*, types::ProtocolMessage};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum StartProtocol {
Client(ClientHello),
Ext(ExtHello),
Core(CoreHello),
Admin(AdminRequest),
App(AppHello),
AppResponse(AppHelloResponse),
}
impl StartProtocol {
pub fn type_id(&self) -> TypeId {
match self {
StartProtocol::Client(a) => a.type_id(),
StartProtocol::Core(a) => a.type_id(),
StartProtocol::Ext(a) => a.type_id(),
StartProtocol::Admin(a) => a.type_id(),
StartProtocol::App(a) => a.type_id(),
StartProtocol::AppResponse(a) => a.type_id(),
}
}
pub fn get_actor(&self) -> Box<dyn EActor> {
match self {
StartProtocol::Client(a) => a.get_actor(),
StartProtocol::Core(a) => a.get_actor(),
StartProtocol::Ext(a) => a.get_actor(),
StartProtocol::Admin(a) => a.get_actor(),
StartProtocol::App(a) => a.get_actor(),
StartProtocol::AppResponse(_) => panic!("AppResponse is not a request"),
}
}
}
impl From<StartProtocol> for ProtocolMessage {
fn from(msg: StartProtocol) -> ProtocolMessage {
ProtocolMessage::Start(msg)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CoreHello {
pub noise: Noise,
#[serde(with = "serde_bytes")]
pub payload: Vec<u8>,
}
impl CoreHello {
pub fn get_actor(&self) -> Box<dyn EActor> {
Actor::<CoreBrokerConnect, CoreBrokerConnectResponse>::new_responder(0)
}
}
impl TryFrom<ProtocolMessage> for CoreBrokerConnectResponse {
type Error = ProtocolError;
fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
if let ProtocolMessage::CoreMessage(CoreMessage::V0(CoreMessageV0::Response(
CoreResponse::V0(CoreResponseV0 {
content: CoreResponseContentV0::BrokerConnectResponse(a),
..
}),
))) = msg
{
Ok(a)
} else {
log_debug!("INVALID {:?}", msg);
Err(ProtocolError::InvalidValue)
}
}
}
impl From<CoreHello> for ProtocolMessage {
fn from(msg: CoreHello) -> ProtocolMessage {
ProtocolMessage::Start(StartProtocol::Core(msg))
}
}
impl From<CoreBrokerConnect> for ProtocolMessage {
fn from(_msg: CoreBrokerConnect) -> ProtocolMessage {
unimplemented!();
}
}
impl Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {}
#[async_trait::async_trait]
impl EActor for Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {
async fn respond(
&mut self,
_msg: ProtocolMessage,
_fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> {
Ok(())
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExtHello {
pub noise: Noise,
#[serde(with = "serde_bytes")]
pub payload: Vec<u8>,
}
impl ExtHello {
pub fn get_actor(&self) -> Box<dyn EActor> {
Actor::<ExtHello, ExtResponse>::new_responder(0)
}
}
impl From<ExtHello> for ProtocolMessage {
fn from(msg: ExtHello) -> ProtocolMessage {
ProtocolMessage::Start(StartProtocol::Ext(msg))
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ClientHello {
Noise3(Noise),
Local,
}
impl ClientHello {
pub fn type_id(&self) -> TypeId {
match self {
ClientHello::Noise3(a) => a.type_id(),
ClientHello::Local => TypeId::of::<ClientHello>(),
}
}
pub fn get_actor(&self) -> Box<dyn EActor> {
Actor::<ClientHello, ServerHello>::new_responder(0)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ServerHelloV0 {
#[serde(with = "serde_bytes")]
pub nonce: Vec<u8>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ServerHello {
V0(ServerHelloV0),
}
impl ServerHello {
pub fn nonce(&self) -> &Vec<u8> {
match self {
ServerHello::V0(o) => &o.nonce,
}
}
}
impl From<ClientHello> for ProtocolMessage {
fn from(msg: ClientHello) -> ProtocolMessage {
ProtocolMessage::Start(StartProtocol::Client(msg))
}
}
impl TryFrom<ProtocolMessage> for ClientHello {
type Error = ProtocolError;
fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
if let ProtocolMessage::Start(StartProtocol::Client(a)) = msg {
Ok(a)
} else {
Err(ProtocolError::InvalidValue)
}
}
}
impl TryFrom<ProtocolMessage> for ServerHello {
type Error = ProtocolError;
fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
if let ProtocolMessage::ServerHello(server_hello) = msg {
Ok(server_hello)
} else {
Err(ProtocolError::InvalidValue)
}
}
}
impl From<ServerHello> for ProtocolMessage {
fn from(msg: ServerHello) -> ProtocolMessage {
ProtocolMessage::ServerHello(msg)
}
}
impl Actor<'_, ClientHello, ServerHello> {}
#[async_trait::async_trait]
impl EActor for Actor<'_, ClientHello, ServerHello> {
async fn respond(
&mut self,
msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> {
let _req = ClientHello::try_from(msg)?;
let res = ServerHello::V0(ServerHelloV0 { nonce: vec![] });
fsm.lock().await.send(res.into()).await?;
Ok(())
}
}
impl Actor<'_, ExtHello, ExtResponse> {}
#[async_trait::async_trait]
impl EActor for Actor<'_, ExtHello, ExtResponse> {
async fn respond(
&mut self,
_msg: ProtocolMessage,
_fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> {
Ok(())
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AppHello {
pub noise: Noise,
pub user: Option<UserId>, pub info: ClientInfo,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AppHelloResponse {
pub result: u16,
}
impl AppHello {
pub fn get_actor(&self) -> Box<dyn EActor> {
Actor::<AppHello, AppHelloResponse>::new_responder(0)
}
}
impl From<AppHello> for ProtocolMessage {
fn from(msg: AppHello) -> ProtocolMessage {
ProtocolMessage::Start(StartProtocol::App(msg))
}
}
impl From<AppHelloResponse> for ProtocolMessage {
fn from(msg: AppHelloResponse) -> ProtocolMessage {
ProtocolMessage::Start(StartProtocol::AppResponse(msg))
}
}
impl TryFrom<ProtocolMessage> for AppHelloResponse {
type Error = ProtocolError;
fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
if let ProtocolMessage::Start(StartProtocol::AppResponse(res)) = msg {
Ok(res)
} else {
Err(ProtocolError::InvalidValue)
}
}
}
impl Actor<'_, AppHello, AppHelloResponse> {}
#[async_trait::async_trait]
impl EActor for Actor<'_, AppHello, AppHelloResponse> {
async fn respond(
&mut self,
_msg: ProtocolMessage,
_fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> {
Ok(())
}
}