extern crate alloc;
mod metrics;
mod reports;
mod types;
pub use metrics::*;
pub use reports::*;
pub use types::*;
use alloc::string::String;
use alloc::vec::Vec;
use spin::Mutex;
static ANALYTICS_COLLECTOR: Mutex<Option<AnalyticsCollector>> = Mutex::new(None);
pub fn init() {
let mut collector = ANALYTICS_COLLECTOR.lock();
if collector.is_none() {
*collector = Some(AnalyticsCollector::new());
}
}
pub struct Analytics;
impl Analytics {
pub fn usage_summary(dataset: &str) -> Result<UsageSummary, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_usage_summary(dataset)
}
pub fn space_breakdown(dataset: &str) -> Result<SpaceBreakdown, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_space_breakdown(dataset)
}
pub fn io_stats(dataset: &str) -> Result<IoStats, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_io_stats(dataset)
}
pub fn capacity_forecast(dataset: &str, days: u32) -> Result<CapacityForecast, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.forecast_capacity(dataset, days)
}
pub fn top_consumers(
dataset: &str,
limit: usize,
) -> Result<Vec<SpaceConsumer>, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_top_consumers(dataset, limit)
}
pub fn file_type_distribution(dataset: &str) -> Result<Vec<FileTypeStats>, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_file_type_distribution(dataset)
}
pub fn dedup_stats(dataset: &str) -> Result<DedupStats, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_dedup_stats(dataset)
}
pub fn compression_stats(dataset: &str) -> Result<CompressionStats, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_compression_stats(dataset)
}
pub fn snapshot_usage(dataset: &str) -> Result<SnapshotUsage, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_snapshot_usage(dataset)
}
pub fn record_data_point(dataset: &str, metric: MetricType, value: u64) {
if let Some(ref mut collector) = *ANALYTICS_COLLECTOR.lock() {
collector.record_metric(dataset, metric, value);
}
}
pub fn get_trend(
dataset: &str,
metric: MetricType,
period: TrendPeriod,
) -> Result<Vec<TrendPoint>, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.get_trend(dataset, metric, period)
}
pub fn full_report(dataset: &str) -> Result<FullReport, AnalyticsError> {
let collector = ANALYTICS_COLLECTOR.lock();
let collector = collector.as_ref().ok_or(AnalyticsError::NotInitialized)?;
collector.generate_full_report(dataset)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_init() {
init();
let collector = ANALYTICS_COLLECTOR.lock();
assert!(collector.is_some());
}
}