//! RPC method registration: plugins expose methods that callers (PHP workers
//! or external admin tools) can invoke on the master.

use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;

use anyhow::Result;
use async_trait::async_trait;
use bytes::Bytes;

/// Static description of an RPC method (advertised at server start; used
/// for introspection and `folk admin list-methods`).
#[derive(Debug, Clone)]
pub struct RpcMethodDef {
    /// Method name, dotted: `"http.connections"`, `"jobs.stats"`.
    pub name: String,
    /// Human-readable description for documentation / admin UIs.
    pub description: String,
}

impl RpcMethodDef {
    pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
        Self {
            name: name.into(),
            description: description.into(),
        }
    }
}

/// Boxed future returned by an RPC handler.
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

/// Type alias for an RPC handler: takes raw request bytes, returns raw response bytes.
pub type RpcHandler = Arc<dyn Fn(Bytes) -> BoxFuture<'static, Result<Bytes>> + Send + Sync>;

/// Allows plugins to register RPC method handlers at boot.
///
/// `folk-core` provides the concrete implementation.
#[async_trait]
pub trait RpcRegistrar: Send + Sync + 'static {
    /// Register a method by name. The handler receives raw request bytes and
    /// returns raw response bytes (typically MessagePack-encoded payloads).
    async fn register_raw(&self, name: String, handler: RpcHandler);
}
