//! Network Usage Metering

use serde::{Deserialize, Serialize};

/// Network bandwidth usage metrics
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct NetworkUsage {
    /// Ingress bytes (incoming)
    pub ingress_bytes: u64,
    /// Egress bytes (outgoing)
    pub egress_bytes: u64,
    /// Number of P2P connections
    pub connections: u32,
    /// Cross-shard messages sent
    pub cross_shard_messages: u64,
}

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

    /// Add ingress bandwidth
    pub fn with_ingress(mut self, bytes: u64) -> Self {
        self.ingress_bytes = bytes;
        self
    }

    /// Add egress bandwidth
    pub fn with_egress(mut self, bytes: u64) -> Self {
        self.egress_bytes = bytes;
        self
    }

    /// Add connections
    pub fn with_connections(mut self, count: u32) -> Self {
        self.connections = count;
        self
    }

    /// Add cross-shard messages
    pub fn with_cross_shard(mut self, count: u64) -> Self {
        self.cross_shard_messages = count;
        self
    }

    /// Get total bandwidth in bytes
    pub fn total_bytes(&self) -> u64 {
        self.ingress_bytes + self.egress_bytes
    }

    /// Get ingress in GB
    pub fn ingress_gb(&self) -> f64 {
        self.ingress_bytes as f64 / 1_073_741_824.0
    }

    /// Get egress in GB
    pub fn egress_gb(&self) -> f64 {
        self.egress_bytes as f64 / 1_073_741_824.0
    }

    /// Get total bandwidth in GB
    pub fn total_gb(&self) -> f64 {
        self.total_bytes() as f64 / 1_073_741_824.0
    }
}

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

    #[test]
    fn test_network_usage() {
        let usage = NetworkUsage::new()
            .with_ingress(2_147_483_648) // 2 GB
            .with_egress(1_073_741_824) // 1 GB
            .with_connections(50)
            .with_cross_shard(1000);

        assert_eq!(usage.ingress_gb(), 2.0);
        assert_eq!(usage.egress_gb(), 1.0);
        assert_eq!(usage.total_gb(), 3.0);
    }
}
