//! Health check registration.

use std::collections::HashMap;
use std::sync::Arc;

use async_trait::async_trait;

use crate::rpc::BoxFuture;

/// Status returned by a single plugin's health check.
#[derive(Debug, Clone)]
pub struct HealthStatus {
    /// `true` if the plugin is healthy.
    pub healthy: bool,
    /// Optional message (typically explains why if `healthy` is `false`).
    pub message: Option<String>,
}

impl HealthStatus {
    pub fn ok() -> Self {
        Self {
            healthy: true,
            message: None,
        }
    }

    pub fn degraded(msg: impl Into<String>) -> Self {
        Self {
            healthy: false,
            message: Some(msg.into()),
        }
    }
}

/// Async health check function.
pub type HealthCheckFn = Arc<dyn Fn() -> BoxFuture<'static, HealthStatus> + Send + Sync>;

/// Plugins register health checks here at boot.
#[async_trait]
pub trait HealthRegistry: Send + Sync + 'static {
    /// Register a health check for the named plugin.
    async fn register(&self, plugin_name: String, check: HealthCheckFn);

    /// Run all registered checks and return their results, keyed by plugin name.
    async fn check_all(&self) -> HashMap<String, HealthStatus>;
}
