//! Guidance tools for the MCP server
//!
//! This module provides AI-powered guidance tools to help users navigate
//! the provisioning system, diagnose issues, and find relevant documentation.

use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::process::Command;

use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use tracing::{debug, warn};
use walkdir::WalkDir;

// ============================================================================
// Core Data Structures
// ============================================================================

/// Overall system status information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemStatus {
    /// Nushell version (if installed)
    pub nushell_version: Option<String>,

    /// Whether workspace is properly configured
    pub workspace_configured: bool,

    /// List of available providers
    pub providers: Vec<String>,

    /// Whether orchestrator is running
    pub orchestrator_running: bool,

    /// Status of platform services
    pub services_status: HashMap<String, ServiceStatus>,

    /// List of detected issues
    pub issues: Vec<Issue>,

    /// System paths configuration
    pub paths: SystemPaths,

    /// Additional metadata
    pub metadata: HashMap<String, String>,
}

/// Status of an individual service
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceStatus {
    /// Service name
    pub name: String,

    /// Whether service is running
    pub running: bool,

    /// Service version (if available)
    pub version: Option<String>,

    /// Service health status
    pub health: HealthStatus,

    /// Last check timestamp
    pub last_checked: String,
}

/// Health status enumeration
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum HealthStatus {
    Healthy,
    Degraded,
    Unhealthy,
    Unknown,
}

/// System issue or warning
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Issue {
    /// Issue severity level
    pub severity: IssueSeverity,

    /// Issue category
    pub category: String,

    /// Human-readable issue description
    pub description: String,

    /// Suggested fix
    pub fix: Option<String>,

    /// Link to documentation
    pub docs_link: Option<String>,
}

/// Issue severity levels
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
pub enum IssueSeverity {
    Info,
    Warning,
    Error,
    Critical,
}

/// System paths configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemPaths {
    /// Provisioning root path
    pub provisioning_root: PathBuf,

    /// Workspace directory
    pub workspace_dir: Option<PathBuf>,

    /// Documentation directory
    pub docs_dir: PathBuf,

    /// Configuration directory
    pub config_dir: PathBuf,
}

/// Suggested next action
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NextAction {
    /// Command to run
    pub command: String,

    /// Human-readable description
    pub description: String,

    /// Link to relevant documentation
    pub docs_link: String,

    /// Expected outcome after running command
    pub expected_outcome: String,

    /// Priority level (1-5, where 1 is highest)
    pub priority: u8,
}

/// Documentation reference
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DocReference {
    /// Path to documentation file
    pub path: String,

    /// Document title
    pub title: String,

    /// Relevant snippet from document
    pub snippet: String,

    /// Relevance score (0.0-1.0)
    pub relevance: f32,

    /// Document section/heading
    pub section: Option<String>,
}

/// Diagnosis result from troubleshooter
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Diagnosis {
    /// Error message or symptom
    pub error: String,

    /// Root cause analysis
    pub root_cause: String,

    /// Suggested fixes (ordered by likelihood)
    pub fixes: Vec<Fix>,

    /// Related documentation
    pub related_docs: Vec<DocReference>,

    /// Confidence level (0.0-1.0)
    pub confidence: f32,
}

/// Individual fix suggestion
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Fix {
    /// Fix description
    pub description: String,

    /// Commands to run
    pub commands: Vec<String>,

    /// Expected outcome
    pub expected_outcome: String,

    /// Risk level
    pub risk: RiskLevel,
}

/// Risk level for fixes
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum RiskLevel {
    Low,
    Medium,
    High,
}

/// Configuration validation result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
    /// Whether configuration is valid
    pub valid: bool,

    /// List of validation errors
    pub errors: Vec<ValidationError>,

    /// List of warnings
    pub warnings: Vec<ValidationWarning>,

    /// Suggestions for improvement
    pub suggestions: Vec<String>,

    /// Related documentation
    pub docs: Vec<DocReference>,
}

/// Validation error
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationError {
    /// Error message
    pub message: String,

    /// File path where error occurred
    pub path: String,

    /// Line number (if applicable)
    pub line: Option<usize>,

    /// Suggested fix
    pub fix: Option<String>,
}

/// Validation warning
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationWarning {
    /// Warning message
    pub message: String,

    /// File path
    pub path: String,

    /// Recommendation
    pub recommendation: String,
}

// ============================================================================
// System Status Tool
// ============================================================================

/// Tool for checking overall system status
pub struct SystemStatusTool {
    provisioning_root: PathBuf,
}

impl SystemStatusTool {
    /// Create new system status tool
    pub fn new(provisioning_root: PathBuf) -> Self {
        Self { provisioning_root }
    }

    /// Check comprehensive system status
    pub fn check_system(&self) -> Result<SystemStatus> {
        debug!("Checking system status");

        let mut issues = Vec::new();
        let mut services_status = HashMap::new();

        // Check Nushell installation
        let nushell_version = self.check_nushell_version();
        if nushell_version.is_none() {
            issues.push(Issue {
                severity: IssueSeverity::Critical,
                category: "Prerequisites".to_string(),
                description: "Nushell is not installed or not in PATH".to_string(),
                fix: Some("Install Nushell: brew install nushell".to_string()),
                docs_link: Some("docs/src/guides/from-scratch.md#prerequisites".to_string()),
            });
        }

        // Check workspace configuration
        let workspace_configured = self.check_workspace_configured();
        if !workspace_configured {
            issues.push(Issue {
                severity: IssueSeverity::Warning,
                category: "Configuration".to_string(),
                description: "Workspace not configured".to_string(),
                fix: Some("Run: provisioning workspace init".to_string()),
                docs_link: Some("docs/src/user/WORKSPACE_SWITCHING_GUIDE.md".to_string()),
            });
        }

        // Discover available providers
        let providers = self.discover_providers();
        if providers.is_empty() {
            issues.push(Issue {
                severity: IssueSeverity::Warning,
                category: "Providers".to_string(),
                description: "No providers discovered".to_string(),
                fix: Some("Check provisioning/extensions/providers/ directory".to_string()),
                docs_link: Some("docs/src/development/QUICK_PROVIDER_GUIDE.md".to_string()),
            });
        }

        // Check orchestrator status
        let orchestrator_running = self.check_orchestrator_running();
        services_status.insert(
            "orchestrator".to_string(),
            ServiceStatus {
                name: "orchestrator".to_string(),
                running: orchestrator_running,
                version: None,
                health: if orchestrator_running {
                    HealthStatus::Healthy
                } else {
                    HealthStatus::Unknown
                },
                last_checked: chrono::Utc::now().to_rfc3339(),
            },
        );

        // Check other platform services
        self.check_platform_services(&mut services_status);

        // Build system paths
        let paths = SystemPaths {
            provisioning_root: self.provisioning_root.clone(),
            workspace_dir: self.find_workspace_dir(),
            docs_dir: self.provisioning_root.join("docs"),
            config_dir: self.provisioning_root.join("provisioning/config"),
        };

        // Build metadata
        let mut metadata = HashMap::new();
        metadata.insert("timestamp".to_string(), chrono::Utc::now().to_rfc3339());
        if let Ok(branch) = self.get_git_branch() {
            metadata.insert("git_branch".to_string(), branch);
        }

        Ok(SystemStatus {
            nushell_version,
            workspace_configured,
            providers,
            orchestrator_running,
            services_status,
            issues,
            paths,
            metadata,
        })
    }

    /// Check if Nushell is installed and get version
    fn check_nushell_version(&self) -> Option<String> {
        Command::new("nu")
            .arg("--version")
            .output()
            .ok()
            .and_then(|output| {
                if output.status.success() {
                    String::from_utf8(output.stdout)
                        .ok()
                        .map(|s| s.trim().to_string())
                } else {
                    None
                }
            })
    }

    /// Check if workspace is configured
    fn check_workspace_configured(&self) -> bool {
        // Check for user config file
        let user_config_path = dirs::home_dir()
            .map(|home| home.join("Library/Application Support/provisioning/user_config.yaml"));

        if let Some(path) = user_config_path {
            if path.exists() {
                return true;
            }
        }

        // Check for workspace directory
        self.find_workspace_dir().is_some()
    }

    /// Find workspace directory
    fn find_workspace_dir(&self) -> Option<PathBuf> {
        let workspace_dir = self.provisioning_root.join("workspace");
        if workspace_dir.exists() && workspace_dir.is_dir() {
            Some(workspace_dir)
        } else {
            None
        }
    }

    /// Discover available providers
    fn discover_providers(&self) -> Vec<String> {
        let providers_dir = self
            .provisioning_root
            .join("provisioning/extensions/providers");
        if !providers_dir.exists() {
            return Vec::new();
        }

        std::fs::read_dir(providers_dir)
            .ok()
            .map(|entries| {
                entries
                    .filter_map(|entry| entry.ok())
                    .filter(|entry| entry.path().is_dir())
                    .filter_map(|entry| entry.file_name().to_str().map(|s| s.to_string()))
                    .collect()
            })
            .unwrap_or_default()
    }

    /// Check if orchestrator is running
    fn check_orchestrator_running(&self) -> bool {
        // Try to connect to orchestrator API
        match reqwest::blocking::Client::new()
            .get("http://localhost:9090/health")
            .timeout(std::time::Duration::from_secs(2))
            .send()
        {
            Ok(response) => response.status().is_success(),
            Err(_) => false,
        }
    }

    /// Check platform services status
    fn check_platform_services(&self, services: &mut HashMap<String, ServiceStatus>) {
        let platform_services = vec![
            ("control-center", 3000),
            ("api-gateway", 8080),
            ("mcp-server", 3001),
        ];

        for (service_name, port) in platform_services {
            let running = self.check_service_port(port);
            services.insert(
                service_name.to_string(),
                ServiceStatus {
                    name: service_name.to_string(),
                    running,
                    version: None,
                    health: if running {
                        HealthStatus::Healthy
                    } else {
                        HealthStatus::Unknown
                    },
                    last_checked: chrono::Utc::now().to_rfc3339(),
                },
            );
        }
    }

    /// Check if service is running on given port
    fn check_service_port(&self, port: u16) -> bool {
        match std::net::TcpStream::connect(format!("127.0.0.1:{}", port)) {
            Ok(stream) => {
                // Set a read timeout to ensure we don't hang
                let _ = stream.set_read_timeout(Some(std::time::Duration::from_secs(1)));
                true
            }
            Err(_) => false,
        }
    }

    /// Get current git branch
    fn get_git_branch(&self) -> Result<String> {
        let output = Command::new("git")
            .current_dir(&self.provisioning_root)
            .args(["rev-parse", "--abbrev-ref", "HEAD"])
            .output()?;

        if output.status.success() {
            Ok(String::from_utf8(output.stdout)?.trim().to_string())
        } else {
            Err(anyhow::anyhow!("Failed to get git branch"))
        }
    }
}

// ============================================================================
// Next Action Tool
// ============================================================================

/// Tool for suggesting next actions based on system state
pub struct NextActionTool {
    provisioning_root: PathBuf,
}

impl NextActionTool {
    /// Create new next action tool
    pub fn new(provisioning_root: PathBuf) -> Self {
        Self { provisioning_root }
    }

    /// Suggest next action based on current system state
    pub fn suggest_next_action(&self, current_state: &SystemStatus) -> Result<NextAction> {
        debug!("Suggesting next action based on system state");

        // Priority 1: Critical issues first
        if let Some(critical_issue) = current_state
            .issues
            .iter()
            .find(|i| i.severity == IssueSeverity::Critical)
        {
            return Ok(NextAction {
                command: critical_issue.fix.clone().unwrap_or_default(),
                description: format!("Fix critical issue: {}", critical_issue.description),
                docs_link: critical_issue
                    .docs_link
                    .clone()
                    .unwrap_or_else(|| "docs/src/guides/from-scratch.md".to_string()),
                expected_outcome: format!("Resolve: {}", critical_issue.description),
                priority: 1,
            });
        }

        // Priority 2: Workspace not configured
        if !current_state.workspace_configured {
            return Ok(NextAction {
                command: "provisioning workspace init".to_string(),
                description: "Initialize workspace for provisioning system".to_string(),
                docs_link: "docs/src/user/WORKSPACE_SWITCHING_GUIDE.md".to_string(),
                expected_outcome: "Workspace directory created with initial configuration"
                    .to_string(),
                priority: 2,
            });
        }

        // Priority 3: No providers available
        if current_state.providers.is_empty() {
            return Ok(NextAction {
                command: "provisioning module discover providers".to_string(),
                description: "Discover available cloud providers".to_string(),
                docs_link: "docs/src/development/QUICK_PROVIDER_GUIDE.md".to_string(),
                expected_outcome: "List of available providers (aws, upcloud, local)".to_string(),
                priority: 3,
            });
        }

        // Priority 4: Orchestrator not running
        if !current_state.orchestrator_running {
            return Ok(NextAction {
                command: "cd provisioning/platform/orchestrator && \
                          ./scripts/start-orchestrator.nu --background"
                    .to_string(),
                description: "Start the orchestrator service for workflow management".to_string(),
                docs_link: ".claude/features/orchestrator-architecture.md".to_string(),
                expected_outcome: "Orchestrator service running on port 9090".to_string(),
                priority: 4,
            });
        }

        // Default: Ready to create infrastructure
        Ok(NextAction {
            command: "provisioning server create --check".to_string(),
            description: "Create servers in check mode (no actual resources created)".to_string(),
            docs_link: "docs/src/guides/from-scratch.md".to_string(),
            expected_outcome: "Server creation plan displayed without making changes".to_string(),
            priority: 5,
        })
    }

    /// Get multiple next actions (top N suggestions)
    pub fn suggest_multiple_actions(
        &self,
        current_state: &SystemStatus,
        count: usize,
    ) -> Result<Vec<NextAction>> {
        let mut actions = Vec::new();

        // Add critical fixes
        for issue in &current_state.issues {
            if issue.severity == IssueSeverity::Critical {
                if let Some(fix) = &issue.fix {
                    actions.push(NextAction {
                        command: fix.clone(),
                        description: format!("Fix: {}", issue.description),
                        docs_link: issue.docs_link.clone().unwrap_or_default(),
                        expected_outcome: format!("Resolve: {}", issue.description),
                        priority: 1,
                    });
                }
            }
        }

        // Add standard workflow actions
        if !current_state.workspace_configured {
            actions.push(NextAction {
                command: "provisioning workspace init".to_string(),
                description: "Initialize workspace".to_string(),
                docs_link: "docs/src/user/WORKSPACE_SWITCHING_GUIDE.md".to_string(),
                expected_outcome: "Workspace configured".to_string(),
                priority: 2,
            });
        }

        // Limit to requested count
        actions.truncate(count);
        Ok(actions)
    }
}

// ============================================================================
// Documentation Finder Tool
// ============================================================================

/// Tool for finding relevant documentation
pub struct DocFinderTool {
    provisioning_root: PathBuf,
    docs_cache: HashMap<PathBuf, String>,
}

impl DocFinderTool {
    /// Create new documentation finder tool
    pub fn new(provisioning_root: PathBuf) -> Self {
        Self {
            provisioning_root,
            docs_cache: HashMap::new(),
        }
    }

    /// Find documentation matching query
    pub fn find_docs(&mut self, query: &str, context: Option<&str>) -> Result<Vec<DocReference>> {
        debug!("Finding docs for query: {}", query);

        let docs_dir = self.provisioning_root.join("docs");
        if !docs_dir.exists() {
            warn!("Documentation directory not found: {:?}", docs_dir);
            return Ok(Vec::new());
        }

        let mut results = Vec::new();
        let query_lower = query.to_lowercase();

        // Walk through all markdown files
        for entry in WalkDir::new(&docs_dir)
            .follow_links(true)
            .into_iter()
            .filter_map(|e| e.ok())
        {
            let path = entry.path();
            if path.extension().is_none_or(|ext| ext != "md") {
                continue;
            }

            // Read file content
            let content = self.read_or_cache_file(path)?;
            let content_lower = content.to_lowercase();

            // Calculate relevance score
            let relevance = self.calculate_relevance(&query_lower, &content_lower, context);

            if relevance > 0.1 {
                // Extract relevant snippet
                let snippet = self.extract_snippet(&content, query, 200);

                // Extract title from first heading
                let title = self.extract_title(&content, path);

                results.push(DocReference {
                    path: path
                        .strip_prefix(&self.provisioning_root)
                        .unwrap_or(path)
                        .to_string_lossy()
                        .to_string(),
                    title,
                    snippet,
                    relevance,
                    section: None,
                });
            }
        }

        // Sort by relevance (highest first)
        results.sort_by(|a, b| b.relevance.partial_cmp(&a.relevance).unwrap());

        // Return top 10 results
        results.truncate(10);
        Ok(results)
    }

    /// Read file or get from cache
    fn read_or_cache_file(&mut self, path: &Path) -> Result<String> {
        if let Some(cached) = self.docs_cache.get(path) {
            return Ok(cached.clone());
        }

        let content = std::fs::read_to_string(path)
            .with_context(|| format!("Failed to read file: {:?}", path))?;
        self.docs_cache.insert(path.to_path_buf(), content.clone());
        Ok(content)
    }

    /// Calculate relevance score for document
    fn calculate_relevance(&self, query: &str, content: &str, context: Option<&str>) -> f32 {
        let mut score = 0.0;

        // Exact match in content
        if content.contains(query) {
            score += 0.5;
        }

        // Word matches
        let query_words: Vec<&str> = query.split_whitespace().collect();
        let content_words: Vec<&str> = content.split_whitespace().collect();

        let matches = query_words
            .iter()
            .filter(|qw| content_words.iter().any(|cw| cw.contains(*qw)))
            .count();

        score += (matches as f32 / query_words.len() as f32) * 0.3;

        // Context boost
        if let Some(ctx) = context {
            if content.to_lowercase().contains(&ctx.to_lowercase()) {
                score += 0.2;
            }
        }

        score.min(1.0)
    }

    /// Extract relevant snippet from content
    fn extract_snippet(&self, content: &str, query: &str, max_length: usize) -> String {
        let query_lower = query.to_lowercase();
        let content_lower = content.to_lowercase();

        // Find position of query in content
        if let Some(pos) = content_lower.find(&query_lower) {
            let start = pos.saturating_sub(max_length / 2);
            let end = (pos + query.len() + max_length / 2).min(content.len());

            let mut snippet = content[start..end].to_string();

            // Add ellipsis if truncated
            if start > 0 {
                snippet = format!("...{}", snippet);
            }
            if end < content.len() {
                snippet = format!("{}...", snippet);
            }

            snippet
        } else {
            // Return first N characters if query not found
            content.chars().take(max_length).collect()
        }
    }

    /// Extract title from document
    fn extract_title(&self, content: &str, path: &Path) -> String {
        // Look for first heading (# Title)
        for line in content.lines() {
            if let Some(title) = line.strip_prefix("# ") {
                return title.trim().to_string();
            }
        }

        // Fallback to filename
        path.file_stem()
            .and_then(|s| s.to_str())
            .unwrap_or("Untitled")
            .to_string()
    }
}

// ============================================================================
// Troubleshooter Tool
// ============================================================================

/// Tool for diagnosing issues and suggesting fixes
pub struct TroubleshooterTool {
    provisioning_root: PathBuf,
}

impl TroubleshooterTool {
    /// Create new troubleshooter tool
    pub fn new(provisioning_root: PathBuf) -> Self {
        Self { provisioning_root }
    }

    /// Diagnose issue and suggest fixes
    pub fn diagnose_issue(&self, error: &str, _context: &SystemStatus) -> Result<Diagnosis> {
        debug!("Diagnosing issue: {}", error);

        let error_lower = error.to_lowercase();

        // Pattern matching for common errors
        let (root_cause, fixes, confidence) = if error_lower.contains("nushell")
            || error_lower.contains("command not found: nu")
        {
            (
                "Nushell is not installed or not in PATH".to_string(),
                vec![
                    Fix {
                        description: "Install Nushell via Homebrew".to_string(),
                        commands: vec!["brew install nushell".to_string()],
                        expected_outcome: "Nushell installed and available in PATH".to_string(),
                        risk: RiskLevel::Low,
                    },
                    Fix {
                        description: "Add Nushell to PATH".to_string(),
                        commands: vec!["export PATH=\"$PATH:/path/to/nushell\"".to_string()],
                        expected_outcome: "Nushell accessible from command line".to_string(),
                        risk: RiskLevel::Low,
                    },
                ],
                0.95,
            )
        } else if error_lower.contains("workspace") {
            (
                "Workspace not configured or not found".to_string(),
                vec![Fix {
                    description: "Initialize workspace".to_string(),
                    commands: vec!["provisioning workspace init".to_string()],
                    expected_outcome: "Workspace directory created with configuration".to_string(),
                    risk: RiskLevel::Low,
                }],
                0.9,
            )
        } else if error_lower.contains("orchestrator") || error_lower.contains("connection refused")
        {
            (
                "Orchestrator service not running".to_string(),
                vec![Fix {
                    description: "Start orchestrator service".to_string(),
                    commands: vec![
                        "cd provisioning/platform/orchestrator".to_string(),
                        "./scripts/start-orchestrator.nu --background".to_string(),
                    ],
                    expected_outcome: "Orchestrator running on port 9090".to_string(),
                    risk: RiskLevel::Low,
                }],
                0.85,
            )
        } else if error_lower.contains("provider") {
            (
                "Cloud provider not configured or unavailable".to_string(),
                vec![
                    Fix {
                        description: "Discover available providers".to_string(),
                        commands: vec!["provisioning module discover providers".to_string()],
                        expected_outcome: "List of available providers displayed".to_string(),
                        risk: RiskLevel::Low,
                    },
                    Fix {
                        description: "Check provider configuration".to_string(),
                        commands: vec!["provisioning validate config".to_string()],
                        expected_outcome: "Configuration validation report".to_string(),
                        risk: RiskLevel::Low,
                    },
                ],
                0.75,
            )
        } else {
            (
                "Unknown error - manual investigation required".to_string(),
                vec![Fix {
                    description: "Check system logs".to_string(),
                    commands: vec!["provisioning logs".to_string()],
                    expected_outcome: "System logs displayed for investigation".to_string(),
                    risk: RiskLevel::Low,
                }],
                0.3,
            )
        };

        // Find related documentation
        let mut doc_finder = DocFinderTool::new(self.provisioning_root.clone());
        let related_docs = doc_finder
            .find_docs(error, Some(&root_cause))
            .unwrap_or_default();

        Ok(Diagnosis {
            error: error.to_string(),
            root_cause,
            fixes,
            related_docs,
            confidence,
        })
    }
}

// ============================================================================
// Config Validator Tool
// ============================================================================

/// Tool for validating configuration files
pub struct ConfigValidatorTool {
    provisioning_root: PathBuf,
}

impl ConfigValidatorTool {
    /// Create new config validator tool
    pub fn new(provisioning_root: PathBuf) -> Self {
        Self { provisioning_root }
    }

    /// Validate configuration file
    pub fn validate_config(&self, config_path: &str) -> Result<ValidationResult> {
        debug!("Validating configuration: {}", config_path);

        let full_path = self.provisioning_root.join(config_path);
        if !full_path.exists() {
            return Ok(ValidationResult {
                valid: false,
                errors: vec![ValidationError {
                    message: format!("Configuration file not found: {}", config_path),
                    path: config_path.to_string(),
                    line: None,
                    fix: Some("Check file path and ensure it exists".to_string()),
                }],
                warnings: Vec::new(),
                suggestions: Vec::new(),
                docs: Vec::new(),
            });
        }

        let mut errors = Vec::new();
        let mut warnings = Vec::new();
        let mut suggestions = Vec::new();

        // Validate based on file extension
        let extension = full_path.extension().and_then(|s| s.to_str());

        match extension {
            Some("toml") => {
                // Validate TOML syntax
                if let Err(e) = self.validate_toml(&full_path) {
                    errors.push(ValidationError {
                        message: format!("TOML syntax error: {}", e),
                        path: config_path.to_string(),
                        line: None,
                        fix: Some("Check TOML syntax and format".to_string()),
                    });
                }
            }
            Some("yaml") | Some("yml") => {
                // Validate YAML syntax
                if let Err(e) = self.validate_yaml(&full_path) {
                    errors.push(ValidationError {
                        message: format!("YAML syntax error: {}", e),
                        path: config_path.to_string(),
                        line: None,
                        fix: Some("Check YAML syntax and indentation".to_string()),
                    });
                }
            }
            Some("k") => {
                // KCL file - suggest using KCL compiler
                suggestions.push("Run 'kcl fmt' to format and validate KCL files".to_string());
            }
            _ => {
                warnings.push(ValidationWarning {
                    message: "Unknown configuration file type".to_string(),
                    path: config_path.to_string(),
                    recommendation: "Ensure file extension is .toml, .yaml, or .k".to_string(),
                });
            }
        }

        // Find related documentation
        let mut doc_finder = DocFinderTool::new(self.provisioning_root.clone());
        let docs = doc_finder
            .find_docs("configuration", Some("validation"))
            .unwrap_or_default();

        Ok(ValidationResult {
            valid: errors.is_empty(),
            errors,
            warnings,
            suggestions,
            docs,
        })
    }

    /// Validate TOML file syntax
    fn validate_toml(&self, path: &Path) -> Result<()> {
        let content = std::fs::read_to_string(path)?;
        toml::from_str::<toml::Value>(&content).context("Invalid TOML syntax")?;
        Ok(())
    }

    /// Validate YAML file syntax
    fn validate_yaml(&self, path: &Path) -> Result<()> {
        let content = std::fs::read_to_string(path)?;
        serde_yaml::from_str::<serde_yaml::Value>(&content).context("Invalid YAML syntax")?;
        Ok(())
    }
}

// Include comprehensive tests
#[cfg(test)]
#[path = "guidance_tests.rs"]
mod tests;
