rush_sync_server/commands/performance/
manager.rs

1use crate::core::prelude::*;
2
3pub struct PerformanceManager;
4
5impl PerformanceManager {
6    pub fn get_status() -> Result<String> {
7        let config_data = Self::load_config_values()?;
8        let performance_analysis = Self::analyze_performance(&config_data);
9
10        Self::format_comprehensive_report(&config_data, &performance_analysis)
11    }
12
13    fn load_config_values() -> Result<ConfigData> {
14        let paths = crate::setup::setup_toml::get_config_paths();
15
16        for path in paths {
17            if path.exists() {
18                if let Ok(content) = std::fs::read_to_string(&path) {
19                    let mut config_data = ConfigData::default();
20
21                    for line in content.lines() {
22                        let line = line.trim();
23                        Self::parse_config_line(line, &mut config_data);
24                    }
25
26                    return Ok(config_data);
27                }
28            }
29        }
30
31        Err(AppError::Validation("No config found".to_string()))
32    }
33
34    fn parse_config_line(line: &str, config_data: &mut ConfigData) {
35        if let Some((key, value)) = line.split_once('=') {
36            let key = key.trim();
37            let value = value.trim().trim_matches('"');
38
39            match key {
40                "poll_rate" => {
41                    if let Ok(val) = value.parse::<u64>() {
42                        config_data.poll_rate = val;
43                    }
44                }
45                "typewriter_delay" => {
46                    if let Ok(val) = value.parse::<u64>() {
47                        config_data.typewriter_delay = val;
48                    }
49                }
50                "max_messages" => {
51                    if let Ok(val) = value.parse::<u64>() {
52                        config_data.max_messages = val;
53                    }
54                }
55                "max_history" => {
56                    if let Ok(val) = value.parse::<u64>() {
57                        config_data.max_history = val;
58                    }
59                }
60                "log_level" => {
61                    config_data.log_level = value.to_string();
62                }
63                "current_theme" => {
64                    config_data.current_theme = value.to_string();
65                }
66                _ => {}
67            }
68        }
69    }
70
71    fn analyze_performance(config: &ConfigData) -> PerformanceAnalysis {
72        let fps = 1000.0 / config.poll_rate as f64;
73
74        let poll_status = match config.poll_rate {
75            0 => PerformanceStatus::Critical,
76            1..=15 => PerformanceStatus::Critical,
77            16..=33 => PerformanceStatus::Optimal,
78            34..=50 => PerformanceStatus::Good,
79            51..=100 => PerformanceStatus::Slow,
80            _ => PerformanceStatus::VerySlow,
81        };
82
83        let typewriter_info = if config.typewriter_delay == 0 {
84            TypewriterInfo {
85                chars_per_sec: None,
86                is_active: false,
87            }
88        } else {
89            let chars_per_sec = 1000.0 / config.typewriter_delay as f64;
90            TypewriterInfo {
91                chars_per_sec: Some(chars_per_sec),
92                is_active: true,
93            }
94        };
95
96        let memory_usage = Self::estimate_memory_usage(config);
97
98        PerformanceAnalysis {
99            fps,
100            poll_status,
101            typewriter_info,
102            memory_usage,
103            recommendations: Self::generate_recommendations(config),
104        }
105    }
106
107    fn estimate_memory_usage(config: &ConfigData) -> MemoryUsage {
108        let message_buffer_mb = (config.max_messages * 100) as f64 / 1024.0 / 1024.0;
109        let history_buffer_mb = (config.max_history * 50) as f64 / 1024.0 / 1024.0;
110        let i18n_cache_mb = 0.5;
111
112        MemoryUsage {
113            total_estimated_mb: message_buffer_mb + history_buffer_mb + i18n_cache_mb,
114            message_buffer_mb,
115            history_buffer_mb,
116            i18n_cache_mb,
117        }
118    }
119
120    fn generate_recommendations(config: &ConfigData) -> Vec<String> {
121        let mut recommendations = Vec::new();
122
123        if config.poll_rate < 16 {
124            recommendations
125                .push("⚔ poll_rate < 16ms: Very high CPU load - recommended: 16-33ms".to_string());
126        }
127
128        if config.max_messages > 1000 {
129            recommendations
130                .push("šŸ’¾ Too many messages in buffer - recommended: max 500".to_string());
131        }
132
133        if config.typewriter_delay > 0 && config.typewriter_delay < 10 {
134            recommendations
135                .push("āŒØļø typewriter_delay < 10ms: Very fast - recommended: 30-100ms".to_string());
136        }
137
138        if recommendations.is_empty() {
139            recommendations.push("āœ… All settings optimally configured".to_string());
140        }
141
142        recommendations
143    }
144
145    fn format_comprehensive_report(
146        config: &ConfigData,
147        analysis: &PerformanceAnalysis,
148    ) -> Result<String> {
149        let mut report = String::new();
150
151        report.push_str("šŸ“Š COMPREHENSIVE PERFORMANCE REPORT\n");
152        report.push_str("=".repeat(50).as_str());
153        report.push_str("\n\n");
154
155        report.push_str("šŸŽÆ System Performance\n");
156        report.push_str(&format!(
157            "   • Poll Rate: {}ms ({:.1} FPS) {}\n",
158            config.poll_rate,
159            analysis.fps,
160            Self::get_status_icon(&analysis.poll_status)
161        ));
162
163        if analysis.typewriter_info.is_active {
164            report.push_str(&format!(
165                "   • Typewriter Speed: {}ms ({:.1} chars/sec)\n",
166                config.typewriter_delay,
167                analysis.typewriter_info.chars_per_sec.unwrap_or(0.0)
168            ));
169        } else {
170            report.push_str("   • Typewriter Speed: DISABLED\n");
171        }
172
173        report.push_str("\nšŸ’¾ Memory Usage\n");
174        report.push_str(&format!(
175            "   • Total Estimated: {:.2} MB\n",
176            analysis.memory_usage.total_estimated_mb
177        ));
178        report.push_str(&format!(
179            "   • Message Buffer: {:.2} MB\n",
180            analysis.memory_usage.message_buffer_mb
181        ));
182        report.push_str(&format!(
183            "   • History Buffer: {:.2} MB\n",
184            analysis.memory_usage.history_buffer_mb
185        ));
186        report.push_str(&format!(
187            "   • i18n Cache: {:.2} MB\n",
188            analysis.memory_usage.i18n_cache_mb
189        ));
190
191        report.push_str("\nšŸ’” Recommendations\n");
192        for recommendation in &analysis.recommendations {
193            report.push_str(&format!("   • {}\n", recommendation));
194        }
195
196        report.push_str("\nšŸ”§ Related Commands\n");
197        report.push_str("   • log-level debug - Enable debug logging\n");
198
199        Ok(report)
200    }
201
202    fn get_status_icon(status: &PerformanceStatus) -> &'static str {
203        match status {
204            PerformanceStatus::Critical => "šŸ”„",
205            PerformanceStatus::Optimal => "āœ…",
206            PerformanceStatus::Good => "āœ…",
207            PerformanceStatus::Slow => "āš ļø",
208            PerformanceStatus::VerySlow => "āŒ",
209        }
210    }
211}
212
213#[derive(Debug, Default)]
214struct ConfigData {
215    poll_rate: u64,
216    typewriter_delay: u64,
217    max_messages: u64,
218    max_history: u64,
219    log_level: String,
220    current_theme: String,
221}
222
223#[derive(Debug)]
224struct PerformanceAnalysis {
225    fps: f64,
226    poll_status: PerformanceStatus,
227    typewriter_info: TypewriterInfo,
228    memory_usage: MemoryUsage,
229    recommendations: Vec<String>,
230}
231
232#[derive(Debug)]
233struct MemoryUsage {
234    total_estimated_mb: f64,
235    message_buffer_mb: f64,
236    history_buffer_mb: f64,
237    i18n_cache_mb: f64,
238}
239
240#[derive(Debug)]
241enum PerformanceStatus {
242    Critical,
243    Optimal,
244    Good,
245    Slow,
246    VerySlow,
247}
248
249#[derive(Debug)]
250struct TypewriterInfo {
251    chars_per_sec: Option<f64>,
252    is_active: bool,
253}