//! Storage L2 Usage Metering

use serde::{Deserialize, Serialize};

/// Storage service usage metrics
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct StorageUsage {
    /// Bytes stored during period
    pub bytes_stored: u64,
    /// Bytes retrieved during period
    pub bytes_retrieved: u64,
    /// Number of storage deals created
    pub deals_created: u32,
}

impl StorageUsage {
    /// Create new storage usage
    pub fn new() -> Self {
        Self::default()
    }

    /// Add bytes stored
    pub fn with_stored(mut self, bytes: u64) -> Self {
        self.bytes_stored = bytes;
        self
    }

    /// Add bytes retrieved
    pub fn with_retrieved(mut self, bytes: u64) -> Self {
        self.bytes_retrieved = bytes;
        self
    }

    /// Add deals created
    pub fn with_deals(mut self, count: u32) -> Self {
        self.deals_created = count;
        self
    }

    /// Get total bytes (stored + retrieved)
    pub fn total_bytes(&self) -> u64 {
        self.bytes_stored + self.bytes_retrieved
    }

    /// Convert bytes stored to GB
    pub fn stored_gb(&self) -> f64 {
        self.bytes_stored as f64 / 1_073_741_824.0
    }

    /// Convert bytes retrieved to GB
    pub fn retrieved_gb(&self) -> f64 {
        self.bytes_retrieved as f64 / 1_073_741_824.0
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_storage_usage() {
        let usage = StorageUsage::new()
            .with_stored(1_073_741_824) // 1 GB
            .with_retrieved(536_870_912) // 0.5 GB
            .with_deals(5);

        assert_eq!(usage.stored_gb(), 1.0);
        assert_eq!(usage.retrieved_gb(), 0.5);
        assert_eq!(usage.deals_created, 5);
    }
}
