#!/usr/bin/env -S cargo run --
#![allow(
    dead_code,
    unused_imports,
    unused_variables,
    unused_assignments,
    unused
)]

//! Simple Rust-native MCP Server for Provisioning
//!
//! A minimal working implementation that shows Rust feasibility

use std::path::PathBuf;

use anyhow::Result;
use clap::Parser;
use serde_json::json;
use tracing::{debug, error, info};

mod config;
mod errors;
mod provisioning;
mod tools;

use config::Config;
use provisioning::ProvisioningEngine;
use tools::ProvisioningTools;

#[derive(Parser, Debug)]
#[command(name = "provisioning-mcp-server")]
#[command(about = "Rust-native MCP server for Cloud Native Provisioning")]
#[command(version)]
struct Args {
    /// Configuration file path
    #[arg(short, long, env = "PROVISIONING_MCP_CONFIG")]
    config: Option<PathBuf>,

    /// Provisioning system path
    #[arg(short, long, env = "PROVISIONING_PATH")]
    provisioning_path: Option<PathBuf>,

    /// Debug mode
    #[arg(short, long, env = "PROVISIONING_DEBUG")]
    debug: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
    let args = Args::parse();

    // Initialize tracing
    tracing_subscriber::fmt()
        .with_max_level(if args.debug {
            tracing::Level::DEBUG
        } else {
            tracing::Level::INFO
        })
        .init();

    info!("🦀 Starting Rust-native MCP Server for Provisioning");

    // Load configuration
    let config = Config::load(args.config, args.provisioning_path, args.debug)?;

    info!("Configuration loaded successfully");
    info!("Provisioning path: {}", config.provisioning_path.display());
    info!("AI enabled: {}", config.is_ai_available());

    // Initialize components
    let engine = ProvisioningEngine::new(&config)?;
    let tools = ProvisioningTools::new(&config);

    info!("🚀 MCP Server components initialized");

    // Run basic tests to verify functionality
    test_components(&engine, &tools).await?;

    // Run performance tests
    info!("⚡ Running performance benchmarks...");
    let performance_results = provisioning_mcp_server::performance_test::run_performance_tests();
    println!("\n{}", performance_results);

    info!("✅ Rust MCP Server validation complete");
    Ok(())
}

async fn test_components(engine: &ProvisioningEngine, tools: &ProvisioningTools) -> Result<()> {
    info!("🧪 Testing server components...");

    // Test configuration parsing
    let test_description = "Create 2 servers with 4 CPU cores for kubernetes cluster on AWS";
    match tools.parse_server_description(test_description) {
        Ok(server_json) => {
            info!("✅ Server parsing test passed");
            info!(
                "   Parsed: {} x {} servers for {}",
                server_json
                    .get("count")
                    .and_then(|v| v.as_u64())
                    .unwrap_or(1),
                server_json
                    .get("instance_type")
                    .and_then(|v| v.as_str())
                    .unwrap_or("unknown"),
                server_json
                    .get("purpose")
                    .and_then(|v| v.as_str())
                    .unwrap_or("general")
            );
        }
        Err(e) => {
            error!("❌ Server parsing test failed: {}", e);
        }
    }

    // Test AI status
    let ai_status = tools.get_ai_status()?;
    info!("🤖 AI Status:\n{}", ai_status);

    // Test basic infrastructure status
    match engine.get_status(None, false) {
        Ok(status) => {
            info!("✅ Infrastructure status test passed");
            debug!("Status: {}", status);
        }
        Err(e) => {
            info!(
                "ℹ️ Infrastructure status (expected if no infrastructure exists): {}",
                e
            );
        }
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use tempfile::TempDir;

    /// Create a test config with a temporary provisioning path
    fn create_test_config() -> (Config, TempDir) {
        let temp_dir = TempDir::new().expect("Failed to create temp directory");
        let temp_path = temp_dir.path();

        // Create minimal provisioning directory structure for tests
        let core_path = temp_path.join("core/nulib");
        fs::create_dir_all(&core_path).expect("Failed to create test provisioning dir");

        // Create the provisioning script file
        let script_path = core_path.join("provisioning");
        fs::write(&script_path, "#!/bin/bash\necho 'test provisioning script'")
            .expect("Failed to create test provisioning script");

        let config = Config {
            provisioning_path: temp_path.to_path_buf(),
            ai: config::AIConfig::default(),
            server: config::ServerConfig::default(),
            debug: false,
        };

        (config, temp_dir)
    }

    #[tokio::test]
    async fn test_server_creation() {
        let (config, _temp) = create_test_config();
        let tools = ProvisioningTools::new(&config);

        // Test parsing - the legacy implementation returns the description as-is
        let result = tools.parse_server_description("Create 1 server for web hosting");
        assert!(result.is_ok(), "Failed to parse server description");

        let server_config = result.unwrap();
        // The legacy parse_server_description returns {"description": "..."}
        assert!(server_config.get("description").is_some(), "Missing description field");
        assert_eq!(
            server_config["description"].as_str(),
            Some("Create 1 server for web hosting"),
            "Description mismatch"
        );
    }

    #[test]
    fn test_config_loading() {
        let (config, _temp) = create_test_config();
        assert!(!config.debug, "Debug should be false by default");
        assert!(
            config.provisioning_path.exists(),
            "Provisioning path should exist (it's a temp dir)"
        );
        assert_eq!(
            config.provisioning_path.to_string_lossy().ends_with("provisioning"),
            false,
            "Test path should not end with /provisioning"
        );
    }
}
