/// Integration Example - Demonstrates event-driven tool system
/// 
/// This example shows how to:
/// 1. Register tools with the ToolRegistry
/// 2. Register ToolSystem with EventBus
/// 3. Emit ToolCallRequested events
/// 4. Handle tool execution results via events

use crate::registry::ToolRegistry;
use crate::system::ToolSystem;
use crate::cache::ToolCache;
use crate::examples::{WeatherApiTool, SimpleMathTool};
use lumina_engine::{Event, EventBus, EventType, EventHandler};
use std::sync::Arc;
use tracing::{info, error};

/// Example: Setting up event-driven tool system
pub async fn setup_tool_system(event_bus: Arc<EventBus>) -> (Arc<ToolRegistry>, Arc<ToolSystem>) {
    // Create tool registry
    let registry = Arc::new(ToolRegistry::new());
    
    // Register example tools
    let weather_tool: Arc<dyn crate::tool::Tool> = Arc::new(WeatherApiTool::default());
    let math_tool: Arc<dyn crate::tool::Tool> = Arc::new(SimpleMathTool::default());
    
    registry.register(weather_tool).await;
    registry.register(math_tool).await;
    
    info!("Registered {} tools", registry.count().await);
    
    // Create tool cache
    let cache = Arc::new(ToolCache::default());
    
    // Create ToolSystem
    let tool_system = Arc::new(ToolSystem::new(
        registry.clone(),
        cache,
        event_bus.clone(),
        5000, // 5s timeout
        3,    // 3 retries
        1000, // 1s retry delay
    ));
    
    // Register ToolSystem as event handler
    event_bus.subscribe(tool_system.clone() as Arc<dyn EventHandler>).await;
    
    info!("ToolSystem registered with EventBus");
    
    (registry, tool_system)
}

/// Example: Requesting a tool call via event
pub async fn request_tool_call(
    event_bus: Arc<EventBus>,
    tool_name: &str,
    input: serde_json::Value,
    source: &str,
    seed: u64,
) -> Result<(), String> {
    // Create ToolCallRequested event
    let event = Event::new(
        EventType::ToolCallRequested,
        source.to_string(),
        serde_json::json!({
            "tool_name": tool_name,
            "input": input,
        }),
        seed,
    );
    
    // Publish event (ToolSystem will handle it)
    event_bus.publish(event).await
        .map_err(|e| format!("Failed to publish tool request: {}", e))?;
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_tool_system_setup() {
        let event_bus = Arc::new(EventBus::new(1000));
        let (registry, _tool_system) = setup_tool_system(event_bus).await;
        
        assert!(registry.exists("math").await);
        assert!(registry.exists("weather_api").await);
        assert_eq!(registry.count().await, 2);
    }
}

