//! Plugin system integration for syntaxis-tui
//!
//! This module provides plugin support for extending syntaxis-tui with custom functionality.
//! Plugins can hook into application events and extend functionality without modifying core code.
//!
//! # Usage
//!
//! ```ignore
//! use syntaxis_tui::plugins::PluginManager;
//! use tools_tui_shared::plugin::Plugin;
//!
//! let mut manager = PluginManager::new();
//! manager.register(Box::new(my_plugin))?;
//! manager.enable_all()?;
//! ```

use tools_tui_shared::plugin::{Plugin, PluginContext, PluginRegistry, PluginResult};

/// Plugin system manager for syntaxis-tui
///
/// Wraps the tools_tui_shared PluginRegistry and provides application-specific plugin management.
#[allow(dead_code)]
pub struct PluginManager {
    /// Underlying plugin registry
    registry: PluginRegistry,
}

#[allow(dead_code)]
impl PluginManager {
    /// Create a new plugin manager
    pub fn new() -> Self {
        Self {
            registry: PluginRegistry::new(),
        }
    }

    /// Register a plugin
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - Plugin with the same name is already registered
    /// - Plugin fails to load
    pub fn register(&mut self, plugin: Box<dyn Plugin>) -> PluginResult<()> {
        self.registry.register(plugin)
    }

    /// Enable all registered plugins
    pub fn enable_all(&mut self) -> PluginResult<()> {
        self.registry.enable_all()
    }

    /// Disable all plugins
    pub fn disable_all(&mut self) -> PluginResult<()> {
        self.registry.disable_all()
    }

    /// Send an event to all plugins
    ///
    /// # Events
    ///
    /// Common application events:
    /// - "app_start" - Application started
    /// - "app_exit" - Application exiting
    /// - "project_created" - New project created
    /// - "project_deleted" - Project deleted
    /// - "screen_changed" - Current screen changed
    /// - "nav_up" - Navigation up
    /// - "nav_down" - Navigation down
    pub fn broadcast_event(&mut self, event: &str) -> PluginResult<()> {
        self.registry.broadcast_event(event)
    }

    /// Get number of registered plugins
    pub fn count(&self) -> usize {
        self.registry.count()
    }

    /// List all registered plugins with status
    ///
    /// Returns tuples of (name, version, loaded, enabled)
    pub fn list(&self) -> Vec<(&str, &str, bool, bool)> {
        self.registry.list()
    }

    /// Check if a plugin is enabled
    pub fn is_enabled(&self, name: &str) -> bool {
        self.registry.is_enabled(name)
    }

    /// Get mutable access to plugin context
    pub fn context_mut(&mut self) -> &mut PluginContext {
        self.registry.context_mut()
    }

    /// Get read-only access to plugin context
    pub fn context(&self) -> &PluginContext {
        self.registry.context()
    }
}

impl Default for PluginManager {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    struct TestPlugin;

    impl Plugin for TestPlugin {
        fn name(&self) -> &'static str {
            "test-plugin"
        }

        fn version(&self) -> &'static str {
            "1.0.0"
        }
    }

    #[test]
    fn test_plugin_manager_create() {
        let manager = PluginManager::new();
        assert_eq!(manager.count(), 0);
    }

    #[test]
    fn test_register_plugin() {
        let mut manager = PluginManager::new();
        manager.register(Box::new(TestPlugin)).unwrap();
        assert_eq!(manager.count(), 1);
    }

    #[test]
    fn test_enable_plugins() {
        let mut manager = PluginManager::new();
        manager.register(Box::new(TestPlugin)).unwrap();
        manager.enable_all().unwrap();
        assert!(manager.is_enabled("test-plugin"));
    }

    #[test]
    fn test_list_plugins() {
        let mut manager = PluginManager::new();
        manager.register(Box::new(TestPlugin)).unwrap();
        let list = manager.list();
        assert_eq!(list.len(), 1);
        assert_eq!(list[0].0, "test-plugin");
        assert_eq!(list[0].1, "1.0.0");
    }

    #[test]
    fn test_broadcast_event() {
        let mut manager = PluginManager::new();
        manager.register(Box::new(TestPlugin)).unwrap();
        manager.broadcast_event("test-event").unwrap();
    }
}
