//! DevicePlugin — 统一设备管理插件
//!
//! 提供跨平台的设备操作接口，包括显示、触摸、音频、电池等功能。
//! 通过 Backend trait 实现平台适配，业务插件通过消息与 DevicePlugin 交互。

use crate::core::{
    message::{Destination, Envelope, Message},
    plugin::*,
};
use anyhow::Result;

pub mod backend;
pub use backend::DeviceBackend;

#[cfg(target_os = "linux")]
pub mod linux_arm64;
#[cfg(target_os = "linux")]
pub use linux_arm64::LinuxArm64Backend;

/// DevicePlugin 结构体
///
/// 统一设备管理插件，负责处理所有设备相关的操作。
/// 通过 DeviceBackend trait 实现平台适配，支持多平台。
///
/// # 架构
/// ```text
/// 业务插件 → Message::DeviceCommand → DevicePlugin → DeviceBackend → 硬件
///                                          ↓
///                                   DeviceResponse
/// ```
///
/// # 使用示例
/// ```ignore
/// // 创建 DevicePlugin
/// let backend = Box::new(LinuxArm64Backend::new());
/// let mut plugin = DevicePlugin::new(backend);
///
/// // 初始化
/// plugin.init(ctx)?;
/// plugin.start()?;
///
/// // 发送命令
/// let cmd = Message::DeviceCommand(DeviceCommand::GetDisplayInfo);
/// plugin.handle_message(cmd)?;
/// ```
pub struct DevicePlugin {
    /// 插件上下文（用于发送消息）
    ctx: Option<PluginContext>,
    /// 设备后端实现
    backend: Box<dyn DeviceBackend>,
}

impl DevicePlugin {
    /// 创建新的 DevicePlugin 实例
    ///
    /// # 参数
    /// - `backend`: 设备后端实现（如 LinuxArm64Backend）
    ///
    /// # 示例
    /// ```ignore
    /// let backend = Box::new(LinuxArm64Backend::new());
    /// let plugin = DevicePlugin::new(backend);
    /// ```
    pub fn new(backend: Box<dyn DeviceBackend>) -> Self {
        Self { ctx: None, backend }
    }

    /// 创建使用默认平台后端的 DevicePlugin 实例
    ///
    /// 根据当前平台自动选择合适的后端实现。
    ///
    /// # 示例
    /// ```ignore
    /// let plugin = DevicePlugin::new_default();
    /// ```
    #[cfg(target_os = "linux")]
    pub fn new_default() -> Self {
        Self::new(Box::new(LinuxArm64Backend::new()))
    }
}

impl Plugin for DevicePlugin {
    fn id(&self) -> &str {
        "device"
    }

    fn info(&self) -> PluginInfo {
        PluginInfo {
            name: "Device Manager".to_string(),
            version: env!("CARGO_PKG_VERSION").to_string(),
            description: format!("统一设备管理插件 ({})", self.backend.name()),
            platform: Platform::Any,
        }
    }

    fn capabilities(&self) -> Vec<String> {
        self.backend
            .capabilities()
            .iter()
            .map(|cap| format!("{:?}", cap))
            .collect()
    }

    fn init(&mut self, ctx: PluginContext) -> Result<()> {
        // 初始化后端（传入空配置，未来可从 ctx.config 读取）
        let config = serde_json::json!({});
        self.backend.init(&config)?;
        self.ctx = Some(ctx);
        Ok(())
    }

    fn start(&mut self) -> Result<()> {
        // DevicePlugin 是被动响应式插件，不需要主动启动任务
        Ok(())
    }

    fn handle_message(&mut self, msg: Message) -> Result<()> {
        match msg {
            Message::DeviceCommand(cmd) => {
                // 处理设备命令
                let response = match self.backend.handle_command(cmd) {
                    Ok(resp) => resp,
                    Err(e) => {
                        // 将错误转换为 DeviceResponse::Error，并记录日志
                        // （核心静态插件目前无人消费 DeviceResponse，故至少在此留痕，
                        //   避免设备层故障完全静默——王浩然风险3 建议）
                        eprintln!("[DevicePlugin] 命令处理失败: {e}");
                        crate::core::message::DeviceResponse::Error(e.to_string())
                    }
                };

                // 发送响应消息
                if let Some(ctx) = &self.ctx {
                    let envelope = Envelope {
                        from: self.id().to_string(),
                        to: Destination::Broadcast,
                        message: Message::DeviceResponse(response),
                    };
                    ctx.tx.send(envelope)?;
                }
            }
            Message::Shutdown => {
                self.stop()?;
            }
            _ => {
                // 忽略其他消息
            }
        }
        Ok(())
    }

    fn stop(&mut self) -> Result<()> {
        self.backend.shutdown()?;
        Ok(())
    }
}

#[cfg(test)]
mod tests;
