use super::merging::StatsMerger;
use super::types::{AggregatedStats, AnalysisDepth, StatsMetadata};
use crate::core::stats::basic::BasicStats;
use crate::core::stats::complexity::ComplexityStats;
use crate::core::stats::ratios::RatioStats;
use crate::utils::errors::Result;
use std::collections::BTreeMap;
pub struct StatsAggregator {
version: String,
merger: StatsMerger,
}
impl StatsAggregator {
pub fn new() -> Self {
Self {
version: env!("CARGO_PKG_VERSION").to_string(),
merger: StatsMerger::new(),
}
}
pub fn aggregate_file_stats(
&self,
basic: BasicStats,
complexity: ComplexityStats,
ratios: RatioStats,
) -> AggregatedStats {
let metadata = StatsMetadata {
calculation_time_ms: 0, version: self.version.clone(),
timestamp: chrono::Utc::now().to_rfc3339(),
file_count_analyzed: 1,
total_bytes_analyzed: basic.total_size,
languages_detected: vec!["unknown".to_string()], analysis_depth: AnalysisDepth::Complete,
};
AggregatedStats {
basic,
complexity,
ratios,
metadata,
}
}
pub fn aggregate_project_stats(
&self,
basic: BasicStats,
complexity: ComplexityStats,
ratios: RatioStats,
) -> AggregatedStats {
let languages_detected: Vec<String> = basic.stats_by_extension.keys().cloned().collect();
let metadata = StatsMetadata {
calculation_time_ms: 0, version: self.version.clone(),
timestamp: chrono::Utc::now().to_rfc3339(),
file_count_analyzed: basic.total_files,
total_bytes_analyzed: basic.total_size,
languages_detected,
analysis_depth: AnalysisDepth::Complete,
};
AggregatedStats {
basic,
complexity,
ratios,
metadata,
}
}
pub fn merge_stats(&self, stats_list: Vec<AggregatedStats>) -> Result<AggregatedStats> {
self.merger.merge_stats(stats_list)
}
pub fn get_summary(&self, stats: &AggregatedStats) -> BTreeMap<String, String> {
let mut summary = BTreeMap::new();
summary.insert(
"total_files".to_string(),
stats.basic.total_files.to_string(),
);
summary.insert(
"total_lines".to_string(),
stats.basic.total_lines.to_string(),
);
summary.insert("code_lines".to_string(), stats.basic.code_lines.to_string());
summary.insert(
"functions".to_string(),
stats.complexity.function_count.to_string(),
);
summary.insert(
"avg_complexity".to_string(),
format!("{:.1}", stats.complexity.cyclomatic_complexity),
);
summary.insert(
"quality_score".to_string(),
format!("{:.1}", stats.ratios.quality_metrics.overall_quality_score),
);
summary.insert(
"languages".to_string(),
stats.metadata.languages_detected.len().to_string(),
);
summary
}
pub fn update_timing(stats: &mut AggregatedStats, start_time: std::time::Instant) {
stats.metadata.calculation_time_ms = start_time.elapsed().as_millis() as u64;
}
pub fn merger(&self) -> &StatsMerger {
&self.merger
}
}
impl Default for StatsAggregator {
fn default() -> Self {
Self::new()
}
}