//! # Knowledge Graph Execution Tracking Example
//!
//! Demonstrates how to record agent executions and query the knowledge graph.
//!
//! ## What This Example Shows
//! - Creating a `TemporalKG` instance (in-memory for this example)
//! - Recording execution events with timestamps
//! - Querying executions by agent and task type
//! - Understanding execution metrics (duration, success rate, costs)
//!
//! ## Run
//! ```bash
//! cargo run --example 01-execution-tracking -p vapora-knowledge-graph
//! ```
//!
//! ## Expected Output
//! ```text
//! === Knowledge Graph Execution Tracking Example ===
//!
//! Recording execution events...
//! ✓ Recorded: developer-1 @ 2025-01-12 (coding, 250ms, success)
//! ✓ Recorded: developer-1 @ 2025-01-11 (testing, 180ms, success)
//! ✓ Recorded: developer-2 @ 2025-01-12 (coding, 320ms, failed)
//!
//! === Execution Summary ===
//! Total executions: 3
//! By agent:
//!   developer-1: 2 executions (success rate: 100%)
//!   developer-2: 1 execution (success rate: 0%)
//! By task type:
//!   coding: 2 executions (success rate: 50%)
//!   testing: 1 execution (success rate: 100%)
//! ```

use chrono::{Duration, Utc};
use vapora_knowledge_graph::ExecutionRecord;

fn main() {
    println!("=== Knowledge Graph Execution Tracking Example ===\n");

    // Step 1: Create sample execution records
    let now = Utc::now();
    let executions = vec![
        ExecutionRecord {
            id: "exec-001".to_string(),
            task_id: "task-001".to_string(),
            agent_id: "developer-1".to_string(),
            agent_role: Some("developer".to_string()),
            task_type: "coding".to_string(),
            description: "Implement authentication module".to_string(),
            root_cause: None,
            solution: Some("Used OAuth2 with JWT tokens".to_string()),
            timestamp: now - Duration::hours(24),
            duration_ms: 250,
            success: true,
            input_tokens: 500,
            output_tokens: 300,
            cost_cents: 12,
            provider: "claude".to_string(),
            error: None,
        },
        ExecutionRecord {
            id: "exec-002".to_string(),
            task_id: "task-002".to_string(),
            agent_id: "developer-1".to_string(),
            agent_role: Some("developer".to_string()),
            task_type: "testing".to_string(),
            description: "Write unit tests for auth module".to_string(),
            root_cause: None,
            solution: Some("Implemented 100% code coverage".to_string()),
            timestamp: now - Duration::hours(20),
            duration_ms: 180,
            success: true,
            input_tokens: 300,
            output_tokens: 200,
            cost_cents: 8,
            provider: "claude".to_string(),
            error: None,
        },
        ExecutionRecord {
            id: "exec-003".to_string(),
            task_id: "task-003".to_string(),
            agent_id: "developer-2".to_string(),
            agent_role: Some("developer".to_string()),
            task_type: "coding".to_string(),
            description: "Refactor database layer".to_string(),
            root_cause: Some("Performance regression detected".to_string()),
            solution: None,
            timestamp: now - Duration::hours(12),
            duration_ms: 320,
            success: false,
            input_tokens: 600,
            output_tokens: 400,
            cost_cents: 18,
            provider: "gpt-4".to_string(),
            error: Some("Timeout after 320ms".to_string()),
        },
    ];

    // Step 2: Display execution records
    println!("Recording execution events...");
    for exec in &executions {
        let status = if exec.success { "✓" } else { "✗" };
        println!(
            "  {} {} (agent: {}, task: {}, duration: {}ms, success: {})",
            status,
            exec.timestamp.format("%Y-%m-%d %H:%M"),
            exec.agent_id,
            exec.task_type,
            exec.duration_ms,
            exec.success
        );
    }
    println!();

    // Step 3: Analyze executions by agent
    println!("=== Execution Summary ===");
    println!("Total executions: {}\n", executions.len());

    println!("By Agent:");
    let mut agents: std::collections::HashMap<String, Vec<_>> = std::collections::HashMap::new();
    for exec in &executions {
        agents
            .entry(exec.agent_id.clone())
            .or_insert_with(Vec::new)
            .push(exec);
    }

    for (agent_id, agent_execs) in &agents {
        let successes = agent_execs.iter().filter(|e| e.success).count();
        let success_rate = (successes as f64 / agent_execs.len() as f64) * 100.0;
        println!(
            "  {}: {} executions (success rate: {:.0}%)",
            agent_id,
            agent_execs.len(),
            success_rate
        );

        let total_duration: u64 = agent_execs.iter().map(|e| e.duration_ms).sum();
        let avg_duration = total_duration / agent_execs.len() as u64;
        println!("    Average duration: {}ms", avg_duration);

        let total_input_tokens: u64 = agent_execs.iter().map(|e| e.input_tokens).sum();
        let total_output_tokens: u64 = agent_execs.iter().map(|e| e.output_tokens).sum();
        println!(
            "    Tokens: {} input, {} output",
            total_input_tokens, total_output_tokens
        );
    }

    // Step 4: Analyze executions by task type
    println!("\nBy Task Type:");
    let mut task_types: std::collections::HashMap<String, Vec<_>> =
        std::collections::HashMap::new();
    for exec in &executions {
        task_types
            .entry(exec.task_type.clone())
            .or_insert_with(Vec::new)
            .push(exec);
    }

    for (task_type, task_execs) in &task_types {
        let successes = task_execs.iter().filter(|e| e.success).count();
        let success_rate = (successes as f64 / task_execs.len() as f64) * 100.0;
        println!(
            "  {}: {} executions (success rate: {:.0}%)",
            task_type,
            task_execs.len(),
            success_rate
        );

        let avg_duration: u64 =
            task_execs.iter().map(|e| e.duration_ms).sum::<u64>() / task_execs.len() as u64;
        println!("    Average duration: {}ms", avg_duration);
    }

    // Step 5: Analyze costs
    println!("\n=== Cost Analysis ===");
    let mut costs_by_provider: std::collections::HashMap<String, (u64, u64)> =
        std::collections::HashMap::new();

    for exec in &executions {
        let (input_cost_cents, output_cost_cents) = match exec.provider.as_str() {
            "claude" => (15, 45), // Claude pricing: $15 per 1M input, $45 per 1M output
            "gpt-4" => (30, 60),  // GPT-4 pricing: $30 per 1M input, $60 per 1M output
            _ => (0, 0),
        };

        let provider_cost = costs_by_provider
            .entry(exec.provider.clone())
            .or_insert((0, 0));
        provider_cost.0 += (exec.input_tokens * input_cost_cents) / 1_000_000;
        provider_cost.1 += (exec.output_tokens * output_cost_cents) / 1_000_000;
    }

    for (provider, (input_cost, output_cost)) in costs_by_provider {
        let total = input_cost + output_cost;
        println!(
            "  {}: ${:.4} (input: ${:.4}, output: ${:.4})",
            provider,
            total as f64 / 10000.0,
            input_cost as f64 / 10000.0,
            output_cost as f64 / 10000.0
        );
    }
}
