use actix::prelude::*;

use witnet_net::client::tcp::jsonrpc;
use witnet_net::server::ws::Server;

use crate::types;

pub mod error;
pub mod handlers;
pub mod methods;
pub mod params;
pub mod routes;
mod state;
#[cfg(test)]
mod tests;

pub use error::*;
pub use handlers::*;
pub use params::*;
pub use routes::*;

pub type Result<T> = std::result::Result<T, Error>;

pub type ResponseFuture<T> = actix::ResponseFuture<Result<T>>;

pub type ResponseActFuture<T> = actix::ResponseActFuture<App, Result<T>>;

pub struct App {
    server: Option<Server>,
    params: Params,
    state: state::State,
}

impl Actor for App {
    type Context = Context<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        // Subscribe to new blocks and blocks consolidation notifications from a Witnet node
        self.node_subscribe("blocks", ctx);
        self.node_subscribe("superblocks", ctx);
        self.periodic_node_request(ctx);

        let mut handler =
            jsonrpc_pubsub::PubSubHandler::new(jsonrpc_core::MetaIoHandler::default());
        connect_routes(&mut handler, ctx.address(), Arbiter::current());

        if let Ok(server) = Server::build()
            .handler(handler)
            .addr(self.params.server_addr)
            .start()
        {
            self.server = Some(server);
        }
    }
}
