use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::PathBuf; use std::process::Command; #[derive(Debug, Serialize, Deserialize)] pub struct DiagnosticResult { pub component: String, pub status: DiagnosticStatus, pub message: String, pub suggestions: Vec, } #[derive(Debug, Serialize, Deserialize)] pub enum DiagnosticStatus { OK, Warning, Error, } #[tauri::command] pub async fn run_diagnostic(component: String) -> Result { match component.as_str() { "database" => run_database_diagnostic().await, "web_server" => run_web_server_diagnostic().await, "ssh" => run_ssh_diagnostic().await, "nfs" => run_nfs_diagnostic().await, "smb" => run_smb_diagnostic().await, _ => Err(format!("Unknown component: {}", component)), } } #[tauri::command] pub async fn run_full_diagnostic() -> Result, String> { let mut results = HashMap::new(); results.insert("database".to_string(), run_database_diagnostic().await?); results.insert("web_server".to_string(), run_web_server_diagnostic().await?); results.insert("ssh".to_string(), run_ssh_diagnostic().await?); results.insert("nfs".to_string(), run_nfs_diagnostic().await?); results.insert("smb".to_string(), run_smb_diagnostic().await?); Ok(results) } #[tauri::command] pub async fn apply_diagnostic_repairs(suggestions: Vec) -> Result<(), String> { for suggestion in suggestions { println!("Applying repair: {}", suggestion); } Ok(()) } async fn run_database_diagnostic() -> Result { let db_path = PathBuf::from("data/users/demo.sqlite"); if db_path.exists() { Ok(DiagnosticResult { component: "database".to_string(), status: DiagnosticStatus::OK, message: "Database file exists and accessible".to_string(), suggestions: vec![], }) } else { Ok(DiagnosticResult { component: "database".to_string(), status: DiagnosticStatus::Error, message: "Database file not found".to_string(), suggestions: vec![ "Run database initialization to create the database".to_string(), ], }) } } async fn run_web_server_diagnostic() -> Result { let output = Command::new("lsof") .args(&["-i", ":11438"]) .output(); match output { Ok(output) => { if output.status.success() && !output.stdout.is_empty() { Ok(DiagnosticResult { component: "web_server".to_string(), status: DiagnosticStatus::OK, message: "Web server is running on port 11438".to_string(), suggestions: vec![], }) } else { Ok(DiagnosticResult { component: "web_server".to_string(), status: DiagnosticStatus::Warning, message: "Web server is not running on port 11438".to_string(), suggestions: vec![ "Start the web server using 'cargo run -- display'".to_string(), ], }) } } Err(e) => { Ok(DiagnosticResult { component: "web_server".to_string(), status: DiagnosticStatus::Error, message: format!("Failed to check web server status: {}", e), suggestions: vec![], }) } } } async fn run_ssh_diagnostic() -> Result { Ok(DiagnosticResult { component: "ssh".to_string(), status: DiagnosticStatus::OK, message: "SSH server is not configured".to_string(), suggestions: vec![ "Configure SSH server in the settings".to_string(), ], }) } async fn run_nfs_diagnostic() -> Result { Ok(DiagnosticResult { component: "nfs".to_string(), status: DiagnosticStatus::OK, message: "NFS server is not configured".to_string(), suggestions: vec![ "Configure NFS server in the settings".to_string(), ], }) } async fn run_smb_diagnostic() -> Result { Ok(DiagnosticResult { component: "smb".to_string(), status: DiagnosticStatus::OK, message: "SMB server is not configured".to_string(), suggestions: vec![ "Configure SMB server in the settings".to_string(), ], }) }