1use crate::chaos_utilities::ChaosConfig;
10use crate::intelligent_behavior::config::IntelligentBehaviorConfig;
11use crate::latency::{LatencyDistribution, LatencyProfile};
12use serde::{Deserialize, Serialize};
13use std::sync::Arc;
14use tokio::sync::RwLock;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
21#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
22#[serde(rename_all = "snake_case")]
23pub enum RealityLevel {
24 StaticStubs = 1,
26 LightSimulation = 2,
28 ModerateRealism = 3,
30 HighRealism = 4,
32 ProductionChaos = 5,
34}
35
36impl RealityLevel {
37 pub fn value(&self) -> u8 {
39 *self as u8
40 }
41
42 pub fn name(&self) -> &'static str {
44 match self {
45 RealityLevel::StaticStubs => "Static Stubs",
46 RealityLevel::LightSimulation => "Light Simulation",
47 RealityLevel::ModerateRealism => "Moderate Realism",
48 RealityLevel::HighRealism => "High Realism",
49 RealityLevel::ProductionChaos => "Production Chaos",
50 }
51 }
52
53 pub fn description(&self) -> &'static str {
55 match self {
56 RealityLevel::StaticStubs => "Simple, instant responses with no chaos",
57 RealityLevel::LightSimulation => "Minimal latency, basic intelligence",
58 RealityLevel::ModerateRealism => "Some chaos, moderate latency, full intelligence",
59 RealityLevel::HighRealism => "Increased chaos, realistic latency, session state",
60 RealityLevel::ProductionChaos => {
61 "Maximum chaos, production-like latency, full features"
62 }
63 }
64 }
65
66 pub fn from_value(value: u8) -> Option<Self> {
68 match value {
69 1 => Some(RealityLevel::StaticStubs),
70 2 => Some(RealityLevel::LightSimulation),
71 3 => Some(RealityLevel::ModerateRealism),
72 4 => Some(RealityLevel::HighRealism),
73 5 => Some(RealityLevel::ProductionChaos),
74 _ => None,
75 }
76 }
77
78 pub fn all() -> Vec<Self> {
80 vec![
81 RealityLevel::StaticStubs,
82 RealityLevel::LightSimulation,
83 RealityLevel::ModerateRealism,
84 RealityLevel::HighRealism,
85 RealityLevel::ProductionChaos,
86 ]
87 }
88}
89
90impl Default for RealityLevel {
91 fn default() -> Self {
92 RealityLevel::ModerateRealism
93 }
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct RealityConfig {
99 pub level: RealityLevel,
101 pub chaos: ChaosConfig,
103 pub latency: LatencyProfile,
105 pub mockai: IntelligentBehaviorConfig,
107}
108
109impl RealityConfig {
110 pub fn for_level(level: RealityLevel) -> Self {
112 match level {
113 RealityLevel::StaticStubs => Self::level_1_static_stubs(),
114 RealityLevel::LightSimulation => Self::level_2_light_simulation(),
115 RealityLevel::ModerateRealism => Self::level_3_moderate_realism(),
116 RealityLevel::HighRealism => Self::level_4_high_realism(),
117 RealityLevel::ProductionChaos => Self::level_5_production_chaos(),
118 }
119 }
120
121 fn level_1_static_stubs() -> Self {
127 Self {
128 level: RealityLevel::StaticStubs,
129 chaos: ChaosConfig {
130 enabled: false,
131 error_rate: 0.0,
132 delay_rate: 0.0,
133 min_delay_ms: 0,
134 max_delay_ms: 0,
135 status_codes: vec![],
136 inject_timeouts: false,
137 timeout_ms: 0,
138 },
139 latency: LatencyProfile {
140 base_ms: 0,
141 jitter_ms: 0,
142 distribution: LatencyDistribution::Fixed,
143 std_dev_ms: None,
144 pareto_shape: None,
145 min_ms: 0,
146 max_ms: Some(0),
147 tag_overrides: Default::default(),
148 },
149 mockai: IntelligentBehaviorConfig {
150 enabled: false,
151 ..Default::default()
152 },
153 }
154 }
155
156 fn level_2_light_simulation() -> Self {
162 Self {
163 level: RealityLevel::LightSimulation,
164 chaos: ChaosConfig {
165 enabled: false,
166 error_rate: 0.0,
167 delay_rate: 0.0,
168 min_delay_ms: 0,
169 max_delay_ms: 0,
170 status_codes: vec![],
171 inject_timeouts: false,
172 timeout_ms: 0,
173 },
174 latency: LatencyProfile {
175 base_ms: 30,
176 jitter_ms: 20,
177 distribution: LatencyDistribution::Fixed,
178 std_dev_ms: None,
179 pareto_shape: None,
180 min_ms: 10,
181 max_ms: Some(50),
182 tag_overrides: Default::default(),
183 },
184 mockai: IntelligentBehaviorConfig {
185 enabled: true,
186 ..Default::default()
187 },
188 }
189 }
190
191 fn level_3_moderate_realism() -> Self {
197 Self {
198 level: RealityLevel::ModerateRealism,
199 chaos: ChaosConfig {
200 enabled: true,
201 error_rate: 0.05,
202 delay_rate: 0.10,
203 min_delay_ms: 50,
204 max_delay_ms: 200,
205 status_codes: vec![500, 502, 503],
206 inject_timeouts: false,
207 timeout_ms: 0,
208 },
209 latency: LatencyProfile {
210 base_ms: 125,
211 jitter_ms: 75,
212 distribution: LatencyDistribution::Normal,
213 std_dev_ms: Some(30.0),
214 pareto_shape: None,
215 min_ms: 50,
216 max_ms: Some(200),
217 tag_overrides: Default::default(),
218 },
219 mockai: IntelligentBehaviorConfig {
220 enabled: true,
221 ..Default::default()
222 },
223 }
224 }
225
226 fn level_4_high_realism() -> Self {
232 Self {
233 level: RealityLevel::HighRealism,
234 chaos: ChaosConfig {
235 enabled: true,
236 error_rate: 0.10,
237 delay_rate: 0.20,
238 min_delay_ms: 100,
239 max_delay_ms: 500,
240 status_codes: vec![500, 502, 503, 504],
241 inject_timeouts: false,
242 timeout_ms: 0,
243 },
244 latency: LatencyProfile {
245 base_ms: 300,
246 jitter_ms: 200,
247 distribution: LatencyDistribution::Normal,
248 std_dev_ms: Some(80.0),
249 pareto_shape: None,
250 min_ms: 100,
251 max_ms: Some(500),
252 tag_overrides: Default::default(),
253 },
254 mockai: IntelligentBehaviorConfig {
255 enabled: true,
256 performance: crate::intelligent_behavior::config::PerformanceConfig {
257 max_history_length: 100,
258 session_timeout_seconds: 3600,
259 ..Default::default()
260 },
261 ..Default::default()
262 },
263 }
264 }
265
266 fn level_5_production_chaos() -> Self {
272 Self {
273 level: RealityLevel::ProductionChaos,
274 chaos: ChaosConfig {
275 enabled: true,
276 error_rate: 0.15,
277 delay_rate: 0.30,
278 min_delay_ms: 200,
279 max_delay_ms: 2000,
280 status_codes: vec![500, 502, 503, 504, 408],
281 inject_timeouts: true,
282 timeout_ms: 5000,
283 },
284 latency: LatencyProfile {
285 base_ms: 1100,
286 jitter_ms: 900,
287 distribution: LatencyDistribution::Pareto,
288 std_dev_ms: None,
289 pareto_shape: Some(2.0),
290 min_ms: 200,
291 max_ms: Some(2000),
292 tag_overrides: Default::default(),
293 },
294 mockai: IntelligentBehaviorConfig {
295 enabled: true,
296 performance: crate::intelligent_behavior::config::PerformanceConfig {
297 max_history_length: 200,
298 session_timeout_seconds: 7200,
299 ..Default::default()
300 },
301 ..Default::default()
302 },
303 }
304 }
305}
306
307impl Default for RealityConfig {
308 fn default() -> Self {
309 Self::for_level(RealityLevel::default())
310 }
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct RealityPreset {
316 pub name: String,
318 pub description: Option<String>,
320 pub config: RealityConfig,
322 pub metadata: Option<PresetMetadata>,
324}
325
326#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct PresetMetadata {
329 pub created_at: Option<String>,
331 pub author: Option<String>,
333 pub tags: Vec<String>,
335 pub version: Option<String>,
337}
338
339impl Default for PresetMetadata {
340 fn default() -> Self {
341 Self {
342 created_at: None,
343 author: None,
344 tags: vec![],
345 version: Some("1.0".to_string()),
346 }
347 }
348}
349
350#[derive(Debug, Clone)]
356pub struct RealityEngine {
357 config: Arc<RwLock<RealityConfig>>,
359}
360
361impl RealityEngine {
362 pub fn new() -> Self {
364 Self {
365 config: Arc::new(RwLock::new(RealityConfig::default())),
366 }
367 }
368
369 pub fn with_level(level: RealityLevel) -> Self {
371 Self {
372 config: Arc::new(RwLock::new(RealityConfig::for_level(level))),
373 }
374 }
375
376 pub async fn get_level(&self) -> RealityLevel {
378 self.config.read().await.level
379 }
380
381 pub async fn set_level(&self, level: RealityLevel) {
383 let mut config = self.config.write().await;
384 *config = RealityConfig::for_level(level);
385 }
386
387 pub async fn get_config(&self) -> RealityConfig {
389 self.config.read().await.clone()
390 }
391
392 pub async fn get_chaos_config(&self) -> ChaosConfig {
394 self.config.read().await.chaos.clone()
395 }
396
397 pub async fn get_latency_profile(&self) -> LatencyProfile {
399 self.config.read().await.latency.clone()
400 }
401
402 pub async fn get_mockai_config(&self) -> IntelligentBehaviorConfig {
404 self.config.read().await.mockai.clone()
405 }
406
407 pub async fn create_preset(&self, name: String, description: Option<String>) -> RealityPreset {
409 let config = self.config.read().await.clone();
410 RealityPreset {
411 name,
412 description,
413 config,
414 metadata: Some(PresetMetadata {
415 created_at: Some(chrono::Utc::now().to_rfc3339()),
416 author: None,
417 tags: vec![],
418 version: Some("1.0".to_string()),
419 }),
420 }
421 }
422
423 pub async fn apply_preset(&self, preset: RealityPreset) {
425 let mut config = self.config.write().await;
426 *config = preset.config;
427 }
428
429 pub async fn apply_to_config(&self, config: &mut crate::config::ServerConfig) {
435 let reality_config = self.get_config().await;
436
437 if config.reality.enabled {
439 if let Some(ref mut chaos_eng) = config.observability.chaos {
441 chaos_eng.enabled = reality_config.chaos.enabled;
442 if let Some(ref mut fault) = chaos_eng.fault_injection {
443 fault.enabled = reality_config.chaos.enabled;
444 fault.http_error_probability = reality_config.chaos.error_rate;
445 fault.timeout_errors = reality_config.chaos.inject_timeouts;
446 fault.timeout_ms = reality_config.chaos.timeout_ms;
447 }
448 if let Some(ref mut latency) = chaos_eng.latency {
449 latency.enabled = reality_config.latency.base_ms > 0;
450 latency.fixed_delay_ms = Some(reality_config.latency.base_ms);
451 latency.jitter_percent = if reality_config.latency.jitter_ms > 0 {
452 (reality_config.latency.jitter_ms as f64
453 / reality_config.latency.base_ms as f64)
454 .min(1.0)
455 } else {
456 0.0
457 };
458 }
459 }
460 }
461
462 if config.reality.enabled {
464 config.core.default_latency = reality_config.latency.clone();
465 config.core.latency_enabled = reality_config.latency.base_ms > 0;
466 }
467
468 if config.reality.enabled {
470 config.mockai.enabled = reality_config.mockai.enabled;
471 config.mockai.intelligent_behavior = reality_config.mockai.clone();
472 }
473 }
474}
475
476impl Default for RealityEngine {
477 fn default() -> Self {
478 Self::new()
479 }
480}
481
482#[cfg(test)]
483mod tests {
484 use super::*;
485
486 #[test]
487 fn test_reality_level_values() {
488 assert_eq!(RealityLevel::StaticStubs.value(), 1);
489 assert_eq!(RealityLevel::LightSimulation.value(), 2);
490 assert_eq!(RealityLevel::ModerateRealism.value(), 3);
491 assert_eq!(RealityLevel::HighRealism.value(), 4);
492 assert_eq!(RealityLevel::ProductionChaos.value(), 5);
493 }
494
495 #[test]
496 fn test_reality_level_from_value() {
497 assert_eq!(RealityLevel::from_value(1), Some(RealityLevel::StaticStubs));
498 assert_eq!(RealityLevel::from_value(3), Some(RealityLevel::ModerateRealism));
499 assert_eq!(RealityLevel::from_value(5), Some(RealityLevel::ProductionChaos));
500 assert_eq!(RealityLevel::from_value(0), None);
501 assert_eq!(RealityLevel::from_value(6), None);
502 }
503
504 #[test]
505 fn test_level_1_config() {
506 let config = RealityConfig::for_level(RealityLevel::StaticStubs);
507 assert!(!config.chaos.enabled);
508 assert_eq!(config.latency.base_ms, 0);
509 assert!(!config.mockai.enabled);
510 }
511
512 #[test]
513 fn test_level_5_config() {
514 let config = RealityConfig::for_level(RealityLevel::ProductionChaos);
515 assert!(config.chaos.enabled);
516 assert!(config.chaos.inject_timeouts);
517 assert_eq!(config.chaos.error_rate, 0.15);
518 assert!(config.latency.base_ms >= 200);
519 assert!(config.mockai.enabled);
520 }
521
522 #[tokio::test]
523 async fn test_reality_engine() {
524 let engine = RealityEngine::with_level(RealityLevel::StaticStubs);
525 assert_eq!(engine.get_level().await, RealityLevel::StaticStubs);
526
527 engine.set_level(RealityLevel::ProductionChaos).await;
528 assert_eq!(engine.get_level().await, RealityLevel::ProductionChaos);
529
530 let chaos_config = engine.get_chaos_config().await;
531 assert!(chaos_config.enabled);
532 }
533
534 #[tokio::test]
535 async fn test_preset_creation() {
536 let engine = RealityEngine::with_level(RealityLevel::ModerateRealism);
537 let preset = engine
538 .create_preset("test-preset".to_string(), Some("Test description".to_string()))
539 .await;
540
541 assert_eq!(preset.name, "test-preset");
542 assert_eq!(preset.config.level, RealityLevel::ModerateRealism);
543 assert!(preset.metadata.is_some());
544 }
545}