use std::convert::Infallible;
use async_trait::async_trait;
use hyper::{Body, Request, Response};

use crate::systems::sys_plugin::BroadcastTx;

/// Context given to plugins for side effects like broadcasting.
#[derive(Clone)]
pub struct PluginContext {
    pub broadcast: BroadcastTx,
}

#[async_trait]
pub trait Plugin: Send + Sync {
    async fn plugin_init(&mut self);
    fn plugin_name(&self) -> &str;
    fn plugin_can_handle(&self, req: &Request<Body>) -> bool;

    /// Now receives a reference to `PluginContext` so it can broadcast.
    async fn plugin_handle(
        &self,
        req: Request<Body>,
        ctx: &PluginContext,
    ) -> Result<Response<Body>, Infallible>;
}
