1use crate::environmental_monitor::types::*;
4use anyhow::Result;
5use std::collections::HashMap;
6use std::time::{Duration, SystemTime};
7use tracing::info;
8
9#[derive(Debug)]
11#[allow(dead_code)]
12pub struct EnvironmentalReportingEngine {
13 #[allow(dead_code)]
14 report_templates: HashMap<String, ReportTemplate>,
15 automated_reports: Vec<AutomatedReport>,
16 dashboard_metrics: EnvironmentalDashboardMetrics,
17}
18
19#[derive(Debug, Clone)]
20#[allow(dead_code)]
21struct ReportTemplate {
22 #[allow(dead_code)]
23 template_name: String,
24 sections: Vec<ReportSection>,
25 target_audience: String,
26 frequency: ReportFrequency,
27}
28
29#[allow(dead_code)]
30#[derive(Debug, Clone)]
31struct ReportSection {
32 #[allow(dead_code)]
33 section_name: String,
34 metrics_included: Vec<String>,
35 visualization_type: VisualizationType,
36}
37#[allow(dead_code)]
38#[derive(Debug, Clone)]
39pub struct AutomatedReport {
40 report_id: String,
41 #[allow(dead_code)]
42 generated_at: SystemTime,
43 report_type: String,
44 content: String,
45}
46
47impl EnvironmentalReportingEngine {
48 pub fn new() -> Self {
50 Self {
51 report_templates: Self::initialize_report_templates(),
52 automated_reports: Vec::new(),
53 dashboard_metrics: EnvironmentalDashboardMetrics {
54 total_energy_consumed_kwh: 0.0,
55 total_co2_emissions_kg: 0.0,
56 current_power_usage_watts: 0.0,
57 energy_efficiency_score: 0.0,
58 carbon_intensity_gco2_kwh: 0.0,
59 cost_per_hour_usd: 0.0,
60 trend: TrendDirection::Stable,
61 },
62 }
63 }
64
65 pub async fn generate_environmental_report(
67 &self,
68 report_type: ReportType,
69 ) -> Result<EnvironmentalReport> {
70 info!("Generating environmental impact report: {:?}", report_type);
71
72 let report = match report_type {
73 ReportType::Summary => self.generate_summary_report().await?,
74 ReportType::Detailed => self.generate_detailed_report().await?,
75 ReportType::Technical => self.generate_technical_report().await?,
76 ReportType::Executive => self.generate_executive_report().await?,
77 ReportType::Compliance => self.generate_compliance_report().await?,
78 };
79
80 self.store_automated_report(&report).await?;
82
83 Ok(report)
84 }
85
86 pub async fn generate_daily_report(&self) -> Result<EnvironmentalReport> {
88 let period_start = SystemTime::now() - Duration::from_secs(24 * 3600);
89 let period_end = SystemTime::now();
90
91 Ok(EnvironmentalReport {
92 report_id: format!("daily-{}", chrono::Utc::now().format("%Y%m%d")),
93 report_type: ReportType::Summary,
94 generated_at: SystemTime::now(),
95 period_start,
96 period_end,
97 summary: "Daily environmental impact summary showing energy consumption, carbon emissions, and efficiency metrics".to_string(),
98 metrics: EnvironmentalDashboardMetrics {
99 total_energy_consumed_kwh: 120.5,
100 total_co2_emissions_kg: 48.2,
101 current_power_usage_watts: 750.0,
102 energy_efficiency_score: 0.87,
103 carbon_intensity_gco2_kwh: 400.0,
104 cost_per_hour_usd: 14.46,
105 trend: TrendDirection::Decreasing,
106 },
107 detailed_analysis: "Energy consumption remained within optimal ranges. Peak power usage occurred during training hours (10 AM - 4 PM). Carbon intensity was 12% lower than regional average due to increased renewable energy generation.".to_string(),
108 recommendations: vec![
109 SustainabilityRecommendation {
110 category: RecommendationCategory::Energy,
111 priority: RecommendationPriority::Medium,
112 title: "Schedule training during low-carbon hours".to_string(),
113 description: "Schedule intensive workloads during hours 2-6 AM when carbon intensity is lowest".to_string(),
114 potential_impact: "15% carbon reduction possible".to_string(),
115 implementation_steps: vec![
116 "Analyze workload scheduling patterns".to_string(),
117 "Implement automated scheduling system".to_string(),
118 "Monitor carbon impact improvements".to_string(),
119 ],
120 },
121 SustainabilityRecommendation {
122 category: RecommendationCategory::Performance,
123 priority: RecommendationPriority::Low,
124 title: "Optimize cooling efficiency".to_string(),
125 description: "Implement dynamic cooling adjustments based on workload intensity".to_string(),
126 potential_impact: "8% energy reduction in cooling systems".to_string(),
127 implementation_steps: vec![
128 "Install smart temperature controls".to_string(),
129 "Monitor cooling system efficiency".to_string(),
130 "Adjust cooling based on real-time needs".to_string(),
131 ],
132 },
133 ],
134 charts: vec![
135 ChartData {
136 chart_type: VisualizationType::LineChart,
137 title: "Daily Energy Consumption".to_string(),
138 data_points: vec![
139 ("00:00".to_string(), 45.2),
140 ("06:00".to_string(), 52.1),
141 ("12:00".to_string(), 78.9),
142 ("18:00".to_string(), 65.3),
143 ],
144 labels: vec!["Time".to_string(), "kWh".to_string()],
145 },
146 ChartData {
147 chart_type: VisualizationType::BarChart,
148 title: "Carbon Emissions by Activity".to_string(),
149 data_points: vec![
150 ("Training".to_string(), 32.1),
151 ("Inference".to_string(), 12.8),
152 ("Data Processing".to_string(), 3.3),
153 ],
154 labels: vec!["Activity".to_string(), "kg CO2".to_string()],
155 },
156 ],
157 })
158 }
159
160 pub async fn generate_weekly_report(&self) -> Result<EnvironmentalReport> {
162 let period_start = SystemTime::now() - Duration::from_secs(7 * 24 * 3600);
163 let period_end = SystemTime::now();
164
165 Ok(EnvironmentalReport {
166 report_id: format!("weekly-{}", chrono::Utc::now().format("%Y-W%W")),
167 report_type: ReportType::Summary,
168 generated_at: SystemTime::now(),
169 period_start,
170 period_end,
171 summary: "Weekly environmental impact analysis showing trends and optimization opportunities".to_string(),
172 metrics: EnvironmentalDashboardMetrics {
173 total_energy_consumed_kwh: 843.5,
174 total_co2_emissions_kg: 337.4,
175 current_power_usage_watts: 750.0,
176 energy_efficiency_score: 0.85,
177 carbon_intensity_gco2_kwh: 400.0,
178 cost_per_hour_usd: 101.22,
179 trend: TrendDirection::Decreasing,
180 },
181 detailed_analysis: "Week-over-week improvements: 12% reduction in carbon emissions, 5% improvement in energy efficiency. Training workloads showed 18% better utilization due to batch size optimization.".to_string(),
182 recommendations: vec![
183 SustainabilityRecommendation {
184 category: RecommendationCategory::Sustainability,
185 priority: RecommendationPriority::High,
186 title: "Implement weekly optimization schedule".to_string(),
187 description: "Create recurring optimization cycles to maintain improvement momentum".to_string(),
188 potential_impact: "Sustained 10-15% efficiency improvements".to_string(),
189 implementation_steps: vec![
190 "Schedule weekly efficiency audits".to_string(),
191 "Automate optimization recommendations".to_string(),
192 "Track improvement metrics consistently".to_string(),
193 ],
194 },
195 ],
196 charts: vec![
197 ChartData {
198 chart_type: VisualizationType::LineChart,
199 title: "Weekly Energy Efficiency Trend".to_string(),
200 data_points: vec![
201 ("Week 1".to_string(), 0.80),
202 ("Week 2".to_string(), 0.82),
203 ("Week 3".to_string(), 0.85),
204 ("Week 4".to_string(), 0.85),
205 ],
206 labels: vec!["Week".to_string(), "Efficiency Score".to_string()],
207 },
208 ],
209 })
210 }
211
212 pub async fn generate_monthly_report(&self) -> Result<EnvironmentalReport> {
214 let period_start = SystemTime::now() - Duration::from_secs(30 * 24 * 3600);
215 let period_end = SystemTime::now();
216
217 Ok(EnvironmentalReport {
218 report_id: format!("monthly-{}", chrono::Utc::now().format("%Y-%m")),
219 report_type: ReportType::Detailed,
220 generated_at: SystemTime::now(),
221 period_start,
222 period_end,
223 summary: "Monthly comprehensive analysis of environmental impact, goal progress, and strategic recommendations".to_string(),
224 metrics: EnvironmentalDashboardMetrics {
225 total_energy_consumed_kwh: 3674.2,
226 total_co2_emissions_kg: 1469.7,
227 current_power_usage_watts: 750.0,
228 energy_efficiency_score: 0.83,
229 carbon_intensity_gco2_kwh: 400.0,
230 cost_per_hour_usd: 440.90,
231 trend: TrendDirection::Decreasing,
232 },
233 detailed_analysis: "Monthly highlights: Achieved 65% progress on carbon reduction goal. Cost savings of $127 from optimization initiatives. Implemented 3 of 5 planned efficiency improvements. Regional carbon intensity averaged 15% below baseline.".to_string(),
234 recommendations: vec![
235 SustainabilityRecommendation {
236 category: RecommendationCategory::Performance,
237 priority: RecommendationPriority::High,
238 title: "Focus on model efficiency optimization".to_string(),
239 description: "Prioritize architectural improvements for next month's optimization cycle".to_string(),
240 potential_impact: "20-30% efficiency improvement potential".to_string(),
241 implementation_steps: vec![
242 "Audit current model architectures".to_string(),
243 "Implement pruning and quantization".to_string(),
244 "Measure performance impact".to_string(),
245 "Scale successful optimizations".to_string(),
246 ],
247 },
248 SustainabilityRecommendation {
249 category: RecommendationCategory::Sustainability,
250 priority: RecommendationPriority::Medium,
251 title: "Consider renewable energy procurement".to_string(),
252 description: "Investigate renewable energy contracts for next quarter".to_string(),
253 potential_impact: "40-60% carbon footprint reduction".to_string(),
254 implementation_steps: vec![
255 "Research renewable energy providers".to_string(),
256 "Analyze cost-benefit of renewable contracts".to_string(),
257 "Negotiate renewable energy agreements".to_string(),
258 "Plan transition timeline".to_string(),
259 ],
260 },
261 ],
262 charts: vec![
263 ChartData {
264 chart_type: VisualizationType::LineChart,
265 title: "Monthly Carbon Emissions Trend".to_string(),
266 data_points: vec![
267 ("Week 1".to_string(), 415.2),
268 ("Week 2".to_string(), 380.1),
269 ("Week 3".to_string(), 342.7),
270 ("Week 4".to_string(), 331.7),
271 ],
272 labels: vec!["Week".to_string(), "kg CO2".to_string()],
273 },
274 ChartData {
275 chart_type: VisualizationType::PieChart,
276 title: "Energy Usage by Activity Type".to_string(),
277 data_points: vec![
278 ("Training".to_string(), 2574.0),
279 ("Inference".to_string(), 735.0),
280 ("Data Processing".to_string(), 220.0),
281 ("Development".to_string(), 145.2),
282 ],
283 labels: vec!["Activity".to_string(), "kWh".to_string()],
284 },
285 ],
286 })
287 }
288
289 pub async fn generate_annual_report(&self) -> Result<EnvironmentalReport> {
291 let period_start = SystemTime::now() - Duration::from_secs(365 * 24 * 3600);
292 let period_end = SystemTime::now();
293
294 Ok(EnvironmentalReport {
295 report_id: format!("annual-{}", chrono::Utc::now().format("%Y")),
296 report_type: ReportType::Executive,
297 generated_at: SystemTime::now(),
298 period_start,
299 period_end,
300 summary: "Annual environmental impact summary with strategic insights and long-term sustainability planning".to_string(),
301 metrics: EnvironmentalDashboardMetrics {
302 total_energy_consumed_kwh: 45000.0,
303 total_co2_emissions_kg: 18000.0,
304 current_power_usage_watts: 750.0,
305 energy_efficiency_score: 0.81,
306 carbon_intensity_gco2_kwh: 400.0,
307 cost_per_hour_usd: 5400.0,
308 trend: TrendDirection::Decreasing,
309 },
310 detailed_analysis: "Annual achievements: 18 tonnes CO2 total footprint (equivalent to 41,580 car miles). Implemented sustainability program with 35% efficiency improvement over baseline. Achieved ISO 14001 preliminary compliance. Established carbon offset program covering 60% of emissions.".to_string(),
311 recommendations: vec![
312 SustainabilityRecommendation {
313 category: RecommendationCategory::Sustainability,
314 priority: RecommendationPriority::Critical,
315 title: "Implement comprehensive carbon reduction strategy".to_string(),
316 description: "Develop multi-year carbon neutrality roadmap with specific milestones".to_string(),
317 potential_impact: "Path to carbon neutrality by 2027".to_string(),
318 implementation_steps: vec![
319 "Set science-based carbon reduction targets".to_string(),
320 "Invest in renewable energy infrastructure".to_string(),
321 "Implement advanced carbon accounting".to_string(),
322 "Establish carbon offset verification program".to_string(),
323 ],
324 },
325 SustainabilityRecommendation {
326 category: RecommendationCategory::Performance,
327 priority: RecommendationPriority::High,
328 title: "Invest in next-generation efficient hardware".to_string(),
329 description: "Plan hardware refresh cycle with focus on energy-efficient compute".to_string(),
330 potential_impact: "30-40% efficiency improvement over current hardware".to_string(),
331 implementation_steps: vec![
332 "Evaluate next-generation GPU efficiency".to_string(),
333 "Plan phased hardware upgrade strategy".to_string(),
334 "Implement hardware efficiency monitoring".to_string(),
335 "Track ROI of efficiency investments".to_string(),
336 ],
337 },
338 ],
339 charts: vec![
340 ChartData {
341 chart_type: VisualizationType::LineChart,
342 title: "Annual Carbon Footprint Progress".to_string(),
343 data_points: vec![
344 ("Q1".to_string(), 5200.0),
345 ("Q2".to_string(), 4800.0),
346 ("Q3".to_string(), 4200.0),
347 ("Q4".to_string(), 3800.0),
348 ],
349 labels: vec!["Quarter".to_string(), "kg CO2".to_string()],
350 },
351 ChartData {
352 chart_type: VisualizationType::Gauge,
353 title: "Sustainability Goals Progress".to_string(),
354 data_points: vec![
355 ("Carbon Reduction".to_string(), 72.0),
356 ("Energy Efficiency".to_string(), 65.0),
357 ("Renewable Energy".to_string(), 45.0),
358 ("Waste Reduction".to_string(), 58.0),
359 ],
360 labels: vec!["Goal".to_string(), "Progress %".to_string()],
361 },
362 ],
363 })
364 }
365
366 async fn generate_summary_report(&self) -> Result<EnvironmentalReport> {
368 self.generate_daily_report().await
369 }
370
371 async fn generate_detailed_report(&self) -> Result<EnvironmentalReport> {
372 self.generate_monthly_report().await
373 }
374
375 async fn generate_technical_report(&self) -> Result<EnvironmentalReport> {
376 let mut report = self.generate_monthly_report().await?;
377 report.report_type = ReportType::Technical;
378
379 report.detailed_analysis = format!(
381 "{}\n\nTechnical Details:\n\
382 - Average GPU utilization: 84.2%\n\
383 - Memory bandwidth efficiency: 76.8%\n\
384 - Compute intensity: 12.4 FLOPS/Watt\n\
385 - Cooling system PUE: 1.18\n\
386 - Network energy overhead: 3.2%\n\
387 - Storage system efficiency: 89.1%",
388 report.detailed_analysis
389 );
390
391 report.charts.push(ChartData {
393 chart_type: VisualizationType::Heatmap,
394 title: "Hardware Utilization Matrix".to_string(),
395 data_points: vec![
396 ("GPU-0".to_string(), 85.2),
397 ("GPU-1".to_string(), 82.7),
398 ("CPU-0".to_string(), 45.3),
399 ("Memory".to_string(), 67.8),
400 ],
401 labels: vec!["Component".to_string(), "Utilization %".to_string()],
402 });
403
404 Ok(report)
405 }
406
407 async fn generate_executive_report(&self) -> Result<EnvironmentalReport> {
408 let mut report = self.generate_monthly_report().await?;
409 report.report_type = ReportType::Executive;
410
411 report.summary = "Executive Summary: Monthly environmental performance shows strong progress toward sustainability goals with measurable business benefits including cost reduction and operational efficiency gains.".to_string();
413
414 report.detailed_analysis = "Key Business Impacts:\n\
415 • $127 monthly cost savings from efficiency optimization\n\
416 • 15% reduction in operational energy costs\n\
417 • Improved compliance posture for environmental regulations\n\
418 • Enhanced corporate sustainability credentials\n\
419 • Risk mitigation for carbon pricing exposure\n\n\
420 Strategic Recommendations:\n\
421 • Accelerate renewable energy procurement timeline\n\
422 • Invest in efficiency monitoring infrastructure\n\
423 • Establish formal sustainability governance structure"
424 .to_string();
425
426 Ok(report)
427 }
428
429 async fn generate_compliance_report(&self) -> Result<EnvironmentalReport> {
430 let mut report = self.generate_monthly_report().await?;
431 report.report_type = ReportType::Compliance;
432
433 report.summary = "Environmental Compliance Report: Assessment of current compliance status against environmental regulations and certification requirements.".to_string();
435
436 report.detailed_analysis = "Compliance Status:\n\
437 • ISO 14001: 65% compliance (target: 100%)\n\
438 • Energy Star: 45% compliance (target: 80%)\n\
439 • Carbon Trust Standard: 30% compliance (target: 90%)\n\
440 • Regional emissions reporting: Fully compliant\n\
441 • Energy efficiency disclosure: Fully compliant\n\n\
442 Required Actions:\n\
443 • Implement formal environmental management system\n\
444 • Establish third-party verification processes\n\
445 • Develop comprehensive carbon accounting system\n\
446 • Create audit trail for all environmental metrics"
447 .to_string();
448
449 report.recommendations.push(SustainabilityRecommendation {
451 category: RecommendationCategory::Sustainability,
452 priority: RecommendationPriority::Critical,
453 title: "Accelerate compliance program implementation".to_string(),
454 description: "Fast-track environmental management system implementation to meet regulatory requirements".to_string(),
455 potential_impact: "Full regulatory compliance within 6 months".to_string(),
456 implementation_steps: vec![
457 "Engage environmental compliance consultant".to_string(),
458 "Implement formal environmental management system".to_string(),
459 "Establish third-party verification processes".to_string(),
460 "Schedule compliance audits".to_string(),
461 ],
462 });
463
464 Ok(report)
465 }
466
467 async fn store_automated_report(&self, report: &EnvironmentalReport) -> Result<()> {
469 let automated_report = AutomatedReport {
470 report_id: report.report_id.clone(),
471 generated_at: report.generated_at,
472 report_type: format!("{:?}", report.report_type),
473 content: format!("{}\n\n{}", report.summary, report.detailed_analysis),
474 };
475
476 info!("Stored automated report: {}", automated_report.report_id);
478 Ok(())
479 }
480
481 pub fn update_dashboard_metrics(&mut self, metrics: EnvironmentalDashboardMetrics) {
483 self.dashboard_metrics = metrics;
484 }
485
486 pub fn get_dashboard_metrics(&self) -> &EnvironmentalDashboardMetrics {
488 &self.dashboard_metrics
489 }
490
491 pub fn get_automated_reports(&self) -> &[AutomatedReport] {
493 &self.automated_reports
494 }
495
496 fn initialize_report_templates() -> HashMap<String, ReportTemplate> {
498 let mut templates = HashMap::new();
499
500 templates.insert(
501 "daily_summary".to_string(),
502 ReportTemplate {
503 template_name: "Daily Environmental Summary".to_string(),
504 target_audience: "Operations Team".to_string(),
505 frequency: ReportFrequency::Daily,
506 sections: vec![
507 ReportSection {
508 section_name: "Energy Consumption".to_string(),
509 metrics_included: vec![
510 "total_energy_kwh".to_string(),
511 "peak_power".to_string(),
512 ],
513 visualization_type: VisualizationType::LineChart,
514 },
515 ReportSection {
516 section_name: "Carbon Emissions".to_string(),
517 metrics_included: vec![
518 "total_co2_kg".to_string(),
519 "carbon_intensity".to_string(),
520 ],
521 visualization_type: VisualizationType::BarChart,
522 },
523 ],
524 },
525 );
526
527 templates.insert(
528 "executive_monthly".to_string(),
529 ReportTemplate {
530 template_name: "Executive Monthly Report".to_string(),
531 target_audience: "Executive Leadership".to_string(),
532 frequency: ReportFrequency::Monthly,
533 sections: vec![
534 ReportSection {
535 section_name: "Strategic Metrics".to_string(),
536 metrics_included: vec![
537 "sustainability_score".to_string(),
538 "cost_savings".to_string(),
539 ],
540 visualization_type: VisualizationType::Gauge,
541 },
542 ReportSection {
543 section_name: "Goal Progress".to_string(),
544 metrics_included: vec![
545 "carbon_goal_progress".to_string(),
546 "efficiency_goal_progress".to_string(),
547 ],
548 visualization_type: VisualizationType::Table,
549 },
550 ],
551 },
552 );
553
554 templates
555 }
556
557 pub async fn generate_custom_report(&self, period: Duration) -> Result<EnvironmentalReport> {
559 let period_start = SystemTime::now() - period;
560 let period_end = SystemTime::now();
561
562 Ok(EnvironmentalReport {
563 report_id: format!("custom-{}", chrono::Utc::now().format("%Y%m%d-%H%M")),
564 report_type: ReportType::Summary,
565 generated_at: SystemTime::now(),
566 period_start,
567 period_end,
568 summary: format!("Custom period environmental analysis covering {:.1} days",
569 period.as_secs_f64() / (24.0 * 3600.0)),
570 metrics: self.dashboard_metrics.clone(),
571 detailed_analysis: "Custom period analysis showing environmental metrics and trends for the specified timeframe".to_string(),
572 recommendations: vec![
573 SustainabilityRecommendation {
574 category: RecommendationCategory::Performance,
575 priority: RecommendationPriority::Medium,
576 title: "Continue monitoring trends".to_string(),
577 description: "Maintain current monitoring practices and look for optimization opportunities".to_string(),
578 potential_impact: "Ongoing efficiency improvements".to_string(),
579 implementation_steps: vec![
580 "Review custom period insights".to_string(),
581 "Identify actionable optimization opportunities".to_string(),
582 "Plan implementation of improvements".to_string(),
583 ],
584 },
585 ],
586 charts: vec![
587 ChartData {
588 chart_type: VisualizationType::LineChart,
589 title: "Custom Period Energy Trend".to_string(),
590 data_points: vec![
591 ("Start".to_string(), 100.0),
592 ("Mid".to_string(), 95.5),
593 ("End".to_string(), 88.2),
594 ],
595 labels: vec!["Time".to_string(), "Energy".to_string()],
596 },
597 ],
598 })
599 }
600}
601
602#[cfg(test)]
603mod tests {
604 use super::*;
605
606 #[test]
607 fn test_reporting_engine_creation() {
608 let engine = EnvironmentalReportingEngine::new();
609 assert!(!engine.report_templates.is_empty());
610 }
611
612 #[tokio::test]
613 async fn test_daily_report_generation() {
614 let engine = EnvironmentalReportingEngine::new();
615 let report = engine.generate_daily_report().await.expect("async operation failed");
616
617 assert!(!report.report_id.is_empty());
618 assert!(!report.summary.is_empty());
619 assert!(!report.recommendations.is_empty());
620 assert!(!report.charts.is_empty());
621 }
622
623 #[tokio::test]
624 async fn test_all_report_types() {
625 let engine = EnvironmentalReportingEngine::new();
626
627 let summary_report = engine
628 .generate_environmental_report(ReportType::Summary)
629 .await
630 .expect("async operation failed");
631 let detailed_report = engine
632 .generate_environmental_report(ReportType::Detailed)
633 .await
634 .expect("async operation failed");
635 let technical_report = engine
636 .generate_environmental_report(ReportType::Technical)
637 .await
638 .expect("async operation failed");
639 let executive_report = engine
640 .generate_environmental_report(ReportType::Executive)
641 .await
642 .expect("async operation failed");
643 let compliance_report = engine
644 .generate_environmental_report(ReportType::Compliance)
645 .await
646 .expect("async operation failed");
647
648 assert_eq!(summary_report.report_type, ReportType::Summary);
649 assert_eq!(detailed_report.report_type, ReportType::Detailed);
650 assert_eq!(technical_report.report_type, ReportType::Technical);
651 assert_eq!(executive_report.report_type, ReportType::Executive);
652 assert_eq!(compliance_report.report_type, ReportType::Compliance);
653 }
654
655 #[tokio::test]
656 async fn test_custom_report_generation() {
657 let engine = EnvironmentalReportingEngine::new();
658 let custom_period = Duration::from_secs(7 * 24 * 3600); let report = engine
661 .generate_custom_report(custom_period)
662 .await
663 .expect("async operation failed");
664
665 assert!(report.summary.contains("7.0 days"));
666 assert!(!report.charts.is_empty());
667 }
668
669 #[test]
670 fn test_dashboard_metrics_update() {
671 let mut engine = EnvironmentalReportingEngine::new();
672
673 let new_metrics = EnvironmentalDashboardMetrics {
674 total_energy_consumed_kwh: 250.0,
675 total_co2_emissions_kg: 100.0,
676 current_power_usage_watts: 800.0,
677 energy_efficiency_score: 0.9,
678 carbon_intensity_gco2_kwh: 350.0,
679 cost_per_hour_usd: 15.0,
680 trend: TrendDirection::Decreasing,
681 };
682
683 engine.update_dashboard_metrics(new_metrics.clone());
684
685 let updated_metrics = engine.get_dashboard_metrics();
686 assert_eq!(updated_metrics.total_energy_consumed_kwh, 250.0);
687 assert_eq!(updated_metrics.energy_efficiency_score, 0.9);
688 }
689
690 #[tokio::test]
691 async fn test_report_content_quality() {
692 let engine = EnvironmentalReportingEngine::new();
693 let report = engine.generate_monthly_report().await.expect("async operation failed");
694
695 assert!(report.summary.len() > 50);
697 assert!(report.detailed_analysis.len() > 100);
698 assert!(!report.recommendations.is_empty());
699
700 for rec in &report.recommendations {
702 assert!(!rec.title.is_empty());
703 assert!(!rec.description.is_empty());
704 assert!(!rec.implementation_steps.is_empty());
705 }
706
707 for chart in &report.charts {
709 assert!(!chart.title.is_empty());
710 assert!(!chart.data_points.is_empty());
711 assert!(!chart.labels.is_empty());
712 }
713 }
714}