// Enhanced MCP Tools for Systems Provisioning
// Integrates with new API server, AI agents, and dashboard capabilities

use anyhow::Result;
use serde_json::{json, Value};
use std::process::Command;
use reqwest::Client;

pub struct ProvisioningTools {
    client: Client,
    api_base_url: String,
}

impl ProvisioningTools {
    pub fn new(api_base_url: Option<String>) -> Self {
        Self {
            client: Client::new(),
            api_base_url: api_base_url.unwrap_or_else(|| "http://localhost:3000".to_string()),
        }
    }

    /// Execute provisioning command with enhanced capabilities
    pub async fn execute_provisioning_command(&self, args: &[&str]) -> Result<Value> {
        let output = Command::new("./core/nulib/provisioning")
            .args(args)
            .output()
            .map_err(|e| anyhow::anyhow!("Failed to execute command: {}", e))?;

        let stdout = String::from_utf8_lossy(&output.stdout);
        let stderr = String::from_utf8_lossy(&output.stderr);

        if output.status.success() {
            Ok(json!({
                "success": true,
                "stdout": stdout,
                "stderr": stderr,
                "exit_code": 0
            }))
        } else {
            Ok(json!({
                "success": false,
                "stdout": stdout,
                "stderr": stderr,
                "exit_code": output.status.code().unwrap_or(-1)
            }))
        }
    }

    /// Query infrastructure using AI-powered natural language
    pub async fn ai_query(&self, query: &str, context: Option<&str>) -> Result<Value> {
        let mut args = vec!["ai", "query", "--prompt", query];

        if let Some(ctx) = context {
            args.extend(&["--context", ctx]);
        }

        let output = Command::new("./core/nulib/provisioning")
            .args(&args)
            .output()
            .map_err(|e| ToolError::ExecutionError(format!("AI query failed: {}", e)))?;

        let result = String::from_utf8_lossy(&output.stdout);

        // Try to parse as JSON, fallback to plain text
        if let Ok(parsed) = serde_json::from_str::<Value>(&result) {
            Ok(parsed)
        } else {
            Ok(json!({
                "query": query,
                "response": result.trim(),
                "type": "natural_language_response"
            }))
        }
    }

    /// Get infrastructure status via API
    pub async fn get_infrastructure_status(&self) -> Result<Value> {
        let url = format!("{}/api/v1/query?target=infrastructure", self.api_base_url);

        match self.client.get(&url).send().await {
            Ok(response) => {
                if response.status().is_success() {
                    let data = response.json::<Value>().await
                        .map_err(|e| ToolError::ExecutionError(format!("Failed to parse response: {}", e)))?;
                    Ok(data)
                } else {
                    // Fallback to CLI command
                    self.execute_provisioning_command(&["show", "infrastructure"]).await
                }
            }
            Err(_) => {
                // Fallback to CLI command
                self.execute_provisioning_command(&["show", "infrastructure"]).await
            }
        }
    }

    /// Get system metrics via API
    pub async fn get_system_metrics(&self, timerange: Option<&str>) -> Result<Value> {
        let timerange = timerange.unwrap_or("1h");
        let url = format!("{}/api/v1/metrics?timerange={}", self.api_base_url, timerange);

        match self.client.get(&url).send().await {
            Ok(response) => {
                if response.status().is_success() {
                    let data = response.json::<Value>().await
                        .map_err(|e| ToolError::ExecutionError(format!("Failed to parse metrics: {}", e)))?;
                    Ok(data)
                } else {
                    // Fallback to CLI command
                    self.execute_provisioning_command(&["query", "metrics", "--since", timerange]).await
                }
            }
            Err(_) => {
                // Fallback to CLI command
                self.execute_provisioning_command(&["query", "metrics", "--since", timerange]).await
            }
        }
    }

    /// Get logs with filtering via API
    pub async fn get_logs(&self, level: Option<&str>, since: Option<&str>) -> Result<Value> {
        let level = level.unwrap_or("info");
        let since = since.unwrap_or("1h");
        let url = format!("{}/api/v1/logs?level={}&since={}", self.api_base_url, level, since);

        match self.client.get(&url).send().await {
            Ok(response) => {
                if response.status().is_success() {
                    let data = response.json::<Value>().await
                        .map_err(|e| ToolError::ExecutionError(format!("Failed to parse logs: {}", e)))?;
                    Ok(data)
                } else {
                    // Fallback to CLI command
                    self.execute_provisioning_command(&["logs", "--level", level, "--since", since]).await
                }
            }
            Err(_) => {
                // Fallback to CLI command
                self.execute_provisioning_command(&["logs", "--level", level, "--since", since]).await
            }
        }
    }

    /// Start API server
    pub async fn start_api_server(&self, port: Option<u16>) -> Result<Value> {
        let port = port.unwrap_or(3000);
        let port_str = port.to_string();

        self.execute_provisioning_command(&["api", "start", "--port", &port_str, "--background"]).await
    }

    /// Get API server status
    pub async fn get_api_status(&self) -> Result<Value> {
        let url = format!("{}/health", self.api_base_url);

        match self.client.get(&url).send().await {
            Ok(response) => {
                let status = response.status();
                let data = response.json::<Value>().await
                    .unwrap_or(json!({"status": "unknown"}));

                Ok(json!({
                    "api_available": status.is_success(),
                    "status_code": status.as_u16(),
                    "data": data
                }))
            }
            Err(e) => {
                Ok(json!({
                    "api_available": false,
                    "error": e.to_string()
                }))
            }
        }
    }

    /// Create and start dashboard
    pub async fn create_dashboard(&self, template: Option<&str>, name: Option<&str>) -> Result<Value> {
        let template = template.unwrap_or("full");
        let name = name.unwrap_or("ai-dashboard");

        self.execute_provisioning_command(&["dashboard", "create", template, name]).await
    }

    /// Start existing dashboard
    pub async fn start_dashboard(&self, name: &str, port: Option<u16>) -> Result<Value> {
        let port = port.unwrap_or(8080);
        let port_str = port.to_string();

        self.execute_provisioning_command(&["dashboard", "start", name, &port_str]).await
    }

    /// Start AI agents
    pub async fn start_ai_agents(&self, agents: Option<Vec<&str>>) -> Result<Value> {
        let mut args = vec!["agents", "start"];

        if let Some(agent_list) = agents {
            args.push("--agents");
            args.push(&format!("[{}]", agent_list.join(", ")));
        }

        self.execute_provisioning_command(&args).await
    }

    /// Get AI agents status
    pub async fn get_agents_status(&self) -> Result<Value> {
        self.execute_provisioning_command(&["agents", "status"]).await
    }

    /// Create servers with configuration
    pub async fn create_servers(&self, config: &Value) -> Result<Value> {
        let template = config.get("template").and_then(|v| v.as_str()).unwrap_or("default");
        let count = config.get("count").and_then(|v| v.as_u64()).unwrap_or(1);
        let provider = config.get("provider").and_then(|v| v.as_str()).unwrap_or("local");
        let instance_type = config.get("instance_type").and_then(|v| v.as_str());

        let mut args = vec![
            "server", "create",
            "--template", template,
            "--count", &count.to_string(),
            "--provider", provider
        ];

        if let Some(itype) = instance_type {
            args.extend(&["--instance-type", itype]);
        }

        self.execute_provisioning_command(&args).await
    }

    /// List servers
    pub async fn list_servers(&self, provider: Option<&str>) -> Result<Value> {
        let mut args = vec!["server", "list"];

        if let Some(p) = provider {
            args.extend(&["--provider", p]);
        }

        self.execute_provisioning_command(&args).await
    }

    /// Delete servers
    pub async fn delete_servers(&self, server_names: &[&str]) -> Result<Value> {
        let mut args = vec!["server", "delete"];
        args.extend(server_names);

        self.execute_provisioning_command(&args).await
    }

    /// Create Kubernetes cluster
    pub async fn create_cluster(&self, config: &Value) -> Result<Value> {
        let name = config.get("name").and_then(|v| v.as_str()).unwrap_or("k8s-cluster");
        let nodes = config.get("nodes").and_then(|v| v.as_u64()).unwrap_or(3);
        let provider = config.get("provider").and_then(|v| v.as_str()).unwrap_or("local");

        let args = vec![
            "cluster", "create",
            "--name", name,
            "--nodes", &nodes.to_string(),
            "--provider", provider
        ];

        self.execute_provisioning_command(&args).await
    }

    /// Generate infrastructure from natural language description
    pub async fn generate_infrastructure(&self, description: &str, output_type: Option<&str>) -> Result<Value> {
        let output_type = output_type.unwrap_or("server");

        let args = vec![
            "ai", "template",
            "--prompt", description,
            "--template-type", output_type
        ];

        self.execute_provisioning_command(&args).await
    }

    /// Get cost optimization recommendations
    pub async fn get_cost_optimization(&self) -> Result<Value> {
        self.ai_query("How can I reduce infrastructure costs and optimize spending?", None).await
    }

    /// Get security analysis
    pub async fn get_security_analysis(&self) -> Result<Value> {
        self.ai_query("Perform a security analysis of current infrastructure and identify threats", None).await
    }

    /// Get performance analysis
    pub async fn get_performance_analysis(&self) -> Result<Value> {
        self.ai_query("Analyze system performance and identify bottlenecks", None).await
    }

    /// Predict infrastructure issues
    pub async fn predict_issues(&self, timeframe: Option<&str>) -> Result<Value> {
        let timeframe = timeframe.unwrap_or("next week");
        let query = format!("Predict potential infrastructure issues for {}", timeframe);

        self.ai_query(&query, None).await
    }
}

// Tool definitions for MCP registration
pub fn get_provisioning_tools() -> Vec<Tool> {
    vec![
        Tool {
            name: "execute_provisioning_command".to_string(),
            description: "Execute provisioning CLI commands with enhanced capabilities".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "args": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Command arguments to pass to provisioning CLI"
                    }
                },
                "required": ["args"]
            })
        },
        Tool {
            name: "ai_query".to_string(),
            description: "Query infrastructure using AI-powered natural language processing".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Natural language query about infrastructure"
                    },
                    "context": {
                        "type": "string",
                        "description": "Additional context for the query (optional)"
                    }
                },
                "required": ["query"]
            })
        },
        Tool {
            name: "get_infrastructure_status".to_string(),
            description: "Get current infrastructure status via API or CLI".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "get_system_metrics".to_string(),
            description: "Retrieve system metrics for specified time range".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "timerange": {
                        "type": "string",
                        "description": "Time range for metrics (e.g., '1h', '24h', '7d')",
                        "default": "1h"
                    }
                }
            })
        },
        Tool {
            name: "get_logs".to_string(),
            description: "Retrieve filtered logs from infrastructure".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "level": {
                        "type": "string",
                        "description": "Log level filter (debug, info, warn, error)",
                        "default": "info"
                    },
                    "since": {
                        "type": "string",
                        "description": "Time range for logs (e.g., '1h', '24h')",
                        "default": "1h"
                    }
                }
            })
        },
        Tool {
            name: "start_api_server".to_string(),
            description: "Start the provisioning API server".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "port": {
                        "type": "integer",
                        "description": "Port number for API server",
                        "default": 3000
                    }
                }
            })
        },
        Tool {
            name: "get_api_status".to_string(),
            description: "Check API server availability and status".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "create_dashboard".to_string(),
            description: "Create interactive dashboard using Marimo".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "template": {
                        "type": "string",
                        "description": "Dashboard template (monitoring, infrastructure, full, ai-insights)",
                        "default": "full"
                    },
                    "name": {
                        "type": "string",
                        "description": "Dashboard name",
                        "default": "ai-dashboard"
                    }
                }
            })
        },
        Tool {
            name: "start_dashboard".to_string(),
            description: "Start existing dashboard server".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "Dashboard name to start"
                    },
                    "port": {
                        "type": "integer",
                        "description": "Port number for dashboard",
                        "default": 8080
                    }
                },
                "required": ["name"]
            })
        },
        Tool {
            name: "start_ai_agents".to_string(),
            description: "Start AI agents for intelligent infrastructure monitoring".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "agents": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of agents to start (pattern_detector, cost_optimizer, performance_analyzer, security_monitor, predictor, auto_healer)"
                    }
                }
            })
        },
        Tool {
            name: "get_agents_status".to_string(),
            description: "Get status of all AI agents".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "create_servers".to_string(),
            description: "Create servers with specified configuration".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "config": {
                        "type": "object",
                        "description": "Server configuration",
                        "properties": {
                            "template": {"type": "string", "default": "default"},
                            "count": {"type": "integer", "default": 1},
                            "provider": {"type": "string", "default": "local"},
                            "instance_type": {"type": "string"}
                        }
                    }
                },
                "required": ["config"]
            })
        },
        Tool {
            name: "list_servers".to_string(),
            description: "List all servers, optionally filtered by provider".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "provider": {
                        "type": "string",
                        "description": "Filter by provider (aws, gcp, azure, local)"
                    }
                }
            })
        },
        Tool {
            name: "delete_servers".to_string(),
            description: "Delete specified servers".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "server_names": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Names of servers to delete"
                    }
                },
                "required": ["server_names"]
            })
        },
        Tool {
            name: "create_cluster".to_string(),
            description: "Create Kubernetes cluster with specified configuration".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "config": {
                        "type": "object",
                        "description": "Cluster configuration",
                        "properties": {
                            "name": {"type": "string", "default": "k8s-cluster"},
                            "nodes": {"type": "integer", "default": 3},
                            "provider": {"type": "string", "default": "local"}
                        }
                    }
                },
                "required": ["config"]
            })
        },
        Tool {
            name: "generate_infrastructure".to_string(),
            description: "Generate infrastructure configuration from natural language description".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "description": {
                        "type": "string",
                        "description": "Natural language description of desired infrastructure"
                    },
                    "output_type": {
                        "type": "string",
                        "description": "Type of output (server, cluster, taskserv)",
                        "default": "server"
                    }
                },
                "required": ["description"]
            })
        },
        Tool {
            name: "get_cost_optimization".to_string(),
            description: "Get AI-powered cost optimization recommendations".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "get_security_analysis".to_string(),
            description: "Get comprehensive security analysis using AI agents".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "get_performance_analysis".to_string(),
            description: "Get detailed performance analysis and bottleneck identification".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {}
            })
        },
        Tool {
            name: "predict_issues".to_string(),
            description: "Predict potential infrastructure issues using AI".to_string(),
            input_schema: json!({
                "type": "object",
                "properties": {
                    "timeframe": {
                        "type": "string",
                        "description": "Prediction timeframe (e.g., 'next week', 'next month')",
                        "default": "next week"
                    }
                }
            })
        }
    ]
}
