rush_sync_server/commands/performance/
manager.rs

1// =====================================================
2// FILE: src/commands/performance/manager.rs - BUSINESS LOGIC
3// =====================================================
4
5use crate::core::prelude::*;
6
7/// Zentrale Verwaltung aller Performance-Operationen
8pub struct PerformanceManager;
9
10impl PerformanceManager {
11    /// Zeigt vollständigen Performance-Status
12    pub fn get_status() -> Result<String> {
13        let config_data = Self::load_config_values()?;
14        let performance_analysis = Self::analyze_performance(&config_data);
15        Ok(Self::format_status_report(
16            &config_data,
17            &performance_analysis,
18        ))
19    }
20
21    /// Lädt Config-Werte direkt aus Datei (robust & schnell)
22    fn load_config_values() -> Result<ConfigData> {
23        let paths = crate::setup::setup_toml::get_config_paths();
24
25        for path in paths {
26            if path.exists() {
27                if let Ok(content) = std::fs::read_to_string(&path) {
28                    let mut config_data = ConfigData::default();
29                    config_data.config_path = path.display().to_string();
30                    config_data.config_name = path
31                        .file_name()
32                        .unwrap_or_default()
33                        .to_string_lossy()
34                        .to_string();
35
36                    // ✅ ROBUSTES PARSING (Line-by-Line)
37                    for line in content.lines() {
38                        let line = line.trim();
39                        if line.starts_with("poll_rate") && line.contains('=') {
40                            if let Some(value_str) = line.split('=').nth(1) {
41                                if let Ok(value) = value_str.trim().parse::<u64>() {
42                                    config_data.poll_rate = value;
43                                }
44                            }
45                        } else if line.starts_with("typewriter_delay") && line.contains('=') {
46                            if let Some(value_str) = line.split('=').nth(1) {
47                                if let Ok(value) = value_str.trim().parse::<u64>() {
48                                    config_data.typewriter_delay = value;
49                                }
50                            }
51                        } else if line.starts_with("max_messages") && line.contains('=') {
52                            if let Some(value_str) = line.split('=').nth(1) {
53                                if let Ok(value) = value_str.trim().parse::<u64>() {
54                                    config_data.max_messages = value;
55                                }
56                            }
57                        } else if line.starts_with("max_history") && line.contains('=') {
58                            if let Some(value_str) = line.split('=').nth(1) {
59                                if let Ok(value) = value_str.trim().parse::<u64>() {
60                                    config_data.max_history = value;
61                                }
62                            }
63                        } else if line.starts_with("log_level") && line.contains('=') {
64                            if let Some(value_str) = line.split('=').nth(1) {
65                                config_data.log_level =
66                                    value_str.trim().trim_matches('"').trim().to_string();
67                            }
68                        }
69                    }
70
71                    return Ok(config_data);
72                }
73            }
74        }
75
76        Err(AppError::Validation(
77            "Keine Config-Datei gefunden".to_string(),
78        ))
79    }
80
81    /// Analysiert Performance-Werte und gibt Bewertung zurück
82    fn analyze_performance(config: &ConfigData) -> PerformanceAnalysis {
83        let fps = 1000.0 / config.poll_rate as f64;
84
85        let poll_status = match config.poll_rate {
86            0 => PerformanceStatus::Critical,
87            1..=15 => PerformanceStatus::Critical,
88            16..=33 => PerformanceStatus::Optimal,
89            34..=50 => PerformanceStatus::Good,
90            51..=100 => PerformanceStatus::Slow,
91            _ => PerformanceStatus::VerySlow,
92        };
93
94        let typewriter_info = if config.typewriter_delay == 0 {
95            TypewriterInfo {
96                chars_per_sec: None,
97                is_active: false,
98            }
99        } else {
100            let chars_per_sec = 1000.0 / config.typewriter_delay as f64;
101            TypewriterInfo {
102                chars_per_sec: Some(chars_per_sec),
103                is_active: true,
104            }
105        };
106
107        PerformanceAnalysis {
108            fps,
109            poll_status,
110            typewriter_info,
111        }
112    }
113
114    /// Formatiert den vollständigen Status-Report (i18n-fähig)
115    fn format_status_report(config: &ConfigData, analysis: &PerformanceAnalysis) -> String {
116        let status_icon = match analysis.poll_status {
117            PerformanceStatus::Critical => "🔥",
118            PerformanceStatus::Optimal => "✅",
119            PerformanceStatus::Good => "✅",
120            PerformanceStatus::Slow => "⚠️",
121            PerformanceStatus::VerySlow => "❌",
122        };
123
124        let typewriter_icon = if analysis.typewriter_info.is_active {
125            "⌨️"
126        } else {
127            "🚫"
128        };
129
130        // ✅ i18n STRINGS verwenden statt hardcoded
131        let header = crate::i18n::get_translation("system.commands.performance.header", &[]);
132        let poll_label = crate::i18n::get_translation("system.commands.performance.poll_rate", &[]);
133        let typewriter_label =
134            crate::i18n::get_translation("system.commands.performance.typewriter", &[]);
135        let messages_label =
136            crate::i18n::get_translation("system.commands.performance.max_messages", &[]);
137        let history_label =
138            crate::i18n::get_translation("system.commands.performance.max_history", &[]);
139        let log_label = crate::i18n::get_translation("system.commands.performance.log_level", &[]);
140        let config_label = crate::i18n::get_translation("system.commands.performance.config", &[]);
141        let recommendations =
142            crate::i18n::get_translation("system.commands.performance.recommendations", &[]);
143        let commands_label =
144            crate::i18n::get_translation("system.commands.performance.related_commands", &[]);
145        let config_edit =
146            crate::i18n::get_translation("system.commands.performance.config_edit", &[]);
147        let log_change =
148            crate::i18n::get_translation("system.commands.performance.log_change", &[]);
149        let version_cmd =
150            crate::i18n::get_translation("system.commands.performance.version_cmd", &[]);
151        let restart_cmd =
152            crate::i18n::get_translation("system.commands.performance.restart_cmd", &[]);
153
154        // ✅ STATUS MESSAGE übersetzt
155        let status_message = match analysis.poll_status {
156            PerformanceStatus::Critical => {
157                crate::i18n::get_translation("system.commands.performance.status.critical", &[])
158            }
159            PerformanceStatus::Optimal => {
160                crate::i18n::get_translation("system.commands.performance.status.optimal", &[])
161            }
162            PerformanceStatus::Good => {
163                crate::i18n::get_translation("system.commands.performance.status.good", &[])
164            }
165            PerformanceStatus::Slow => {
166                crate::i18n::get_translation("system.commands.performance.status.slow", &[])
167            }
168            PerformanceStatus::VerySlow => {
169                crate::i18n::get_translation("system.commands.performance.status.very_slow", &[])
170            }
171        };
172
173        // ✅ TYPEWRITER STATUS übersetzt
174        let typewriter_status = if analysis.typewriter_info.is_active {
175            crate::i18n::get_translation(
176                "system.commands.performance.typewriter.active",
177                &[&format!(
178                    "{:.1}",
179                    analysis.typewriter_info.chars_per_sec.unwrap_or(0.0)
180                )],
181            )
182        } else {
183            crate::i18n::get_translation("system.commands.performance.typewriter.disabled", &[])
184        };
185
186        format!(
187            "{}\n\n\
188            🎯 {}: {}ms ({:.1} FPS) {} {}\n\
189            {} {}: {}ms ({})\n\
190            📈 {}: {}\n\
191            📜 {}: {}\n\
192            🎨 {}: {}\n\
193            📍 {}: {}\n\n\
194            💡 {}:\n\
195            {}\n\n\
196            🔧 {}:\n\
197            • {}: {}\n\
198            • {}\n\
199            • {}: 'version'\n\
200            • {}: 'restart'",
201            header,
202            poll_label,
203            config.poll_rate,
204            analysis.fps,
205            status_icon,
206            status_message,
207            typewriter_icon,
208            typewriter_label,
209            config.typewriter_delay,
210            typewriter_status,
211            messages_label,
212            config.max_messages,
213            history_label,
214            config.max_history,
215            log_label,
216            config.log_level.to_uppercase(),
217            config_label,
218            config.config_name,
219            recommendations,
220            crate::i18n::get_translation(
221                "system.commands.performance.recommendations.content",
222                &[]
223            ),
224            commands_label,
225            config_edit,
226            config.config_path,
227            log_change,
228            version_cmd,
229            restart_cmd
230        )
231    }
232}
233
234// =====================================================
235// DATENSTRUKTUREN
236// =====================================================
237
238#[derive(Debug, Default)]
239struct ConfigData {
240    poll_rate: u64,
241    typewriter_delay: u64,
242    max_messages: u64,
243    max_history: u64,
244    log_level: String,
245    config_path: String,
246    config_name: String,
247}
248
249#[derive(Debug)]
250struct PerformanceAnalysis {
251    fps: f64,
252    poll_status: PerformanceStatus,
253    typewriter_info: TypewriterInfo,
254}
255
256#[derive(Debug)]
257enum PerformanceStatus {
258    Critical,
259    Optimal,
260    Good,
261    Slow,
262    VerySlow,
263}
264
265#[derive(Debug)]
266struct TypewriterInfo {
267    chars_per_sec: Option<f64>,
268    is_active: bool,
269}