use tauri::State; use crate::models::*; use crate::profiler::*; use chrono::Utc; use std::process::Command as StdCommand; #[tauri::command] pub fn get_system_stats(state: State, minimal: bool) -> SystemStats { let mut sys = state.sys.lock().unwrap(); let mut profiling = state.profiling.lock().unwrap(); let mut pss_cache = state.pss_cache.lock().unwrap(); let self_pid = std::process::id(); let syspulse_pids = get_syspulse_pids(self_pid, &sys); let snapshot = collect_snapshot(&mut sys, &syspulse_pids, &mut pss_cache, profiling.is_active); if profiling.is_active { profiling.snapshots.push(snapshot.clone()); } let recording_duration = profiling.start_time.map(|s| (Utc::now() - s).num_seconds() as u64).unwrap_or(0); let display_processes = if minimal && !profiling.is_active { Vec::new() } else { let mut p = snapshot.processes.clone(); p.sort_by(|a, b| b.cpu_usage.partial_cmp(&a.cpu_usage).unwrap_or(std::cmp::Ordering::Equal)); p.truncate(50); p }; SystemStats { cpu_usage: snapshot.cpu_usage, total_memory: sys.total_memory(), used_memory: sys.used_memory(), processes: display_processes, is_recording: profiling.is_active, recording_duration } } #[tauri::command] pub fn get_initial_report(state: State) -> Option { state.initial_report.lock().unwrap().clone() } #[tauri::command] pub fn save_report(report: Report) -> Result { let json = serde_json::to_string_pretty(&report).map_err(|e| e.to_string())?; let path = format!("syspulse_report_{}.json", Utc::now().format("%Y%m%d_%H%M%S")); std::fs::write(&path, json).map_err(|e| e.to_string())?; Ok(path) } #[tauri::command] pub fn start_profiling(state: State) { let mut profiling = state.profiling.lock().unwrap(); profiling.is_active = true; profiling.mode = ProfilingMode::Global; profiling.target_pid = None; profiling.start_time = Some(Utc::now()); profiling.snapshots.clear(); } #[tauri::command] pub fn start_targeted_profiling(state: State, pid: u32) { let mut profiling = state.profiling.lock().unwrap(); profiling.is_active = true; profiling.mode = ProfilingMode::Targeted; profiling.target_pid = Some(pid); profiling.start_time = Some(Utc::now()); profiling.snapshots.clear(); } #[tauri::command] pub fn stop_profiling(state: State) -> Report { let mut profiling = state.profiling.lock().unwrap(); profiling.is_active = false; let snapshots: Vec = profiling.snapshots.drain(..).collect(); generate_report(profiling.start_time.unwrap_or(Utc::now()), snapshots, profiling.mode, profiling.target_pid) } #[tauri::command] pub fn run_as_admin(command: String) -> Result { let output = StdCommand::new("pkexec").arg("sh").arg("-c").arg(&command).output().map_err(|e| e.to_string())?; if output.status.success() { Ok(String::from_utf8_lossy(&output.stdout).to_string()) } else { Err(String::from_utf8_lossy(&output.stderr).to_string()) } }