package org.kne.cloud.network.monitor;
import java.util.concurrent.atomic.LongAdder;

/**
 * 高性能网络流量统计器
 * 
 * 设计要点：
 * 1. 数据面使用 LongAdder 无锁累加，完全不阻塞。
 * 2. 控制面使用快照缓存，避免每次都调用 sum() 遍历 Cell。
 * 3. 支持带宽（Bps）、包速率（PPS）、平均包大小（bytes/pkt）统计。
 */
public class BandwidthSampler {

    // 数据面累加器（无锁）
    private final LongAdder packetCount = new LongAdder();
    private final LongAdder byteCount = new LongAdder();

    // 快照缓存（控制面使用，避免高频 sum()）
    private volatile long cachedPacketCount = 0;
    private volatile long cachedByteCount = 0;
    private volatile long lastSnapshotTime = 0;

    // 统计结果缓存
    private volatile double currentBandwidthBps = 0.0;
    private volatile double currentPacketRatePps = 0.0;
    private volatile double currentAvgPacketSize = 0.0;  // 新增：平均包大小（字节/包）

    /**
     * 数据面调用：记录一个包
     * @param packetSizeBytes 包大小（字节）
     */
    public void recordPacket(int packetSizeBytes) {
        packetCount.increment();
        byteCount.add(packetSizeBytes);
    }

    /**
     * 控制面调用：更新统计快照（建议每 1 秒或每 1ms 调用一次）
     * 计算带宽、PPS、平均包大小，并重置累加器
     */
    public void update() {
        long now = System.nanoTime();

        // 取当前累加值（会遍历 Cell，但频率低，可接受）
        long currPackets = packetCount.sumThenReset();
        long currBytes = byteCount.sumThenReset();

        // 计算时间间隔（秒）
        double intervalSec = (lastSnapshotTime == 0) ? 1.0 : (now - lastSnapshotTime) / 1_000_000_000.0;
        if (intervalSec <= 0) intervalSec = 1.0;

        // 更新缓存
        cachedPacketCount = currPackets;
        cachedByteCount = currBytes;

        // 计算指标
        currentBandwidthBps = currBytes / intervalSec;
        currentPacketRatePps = currPackets / intervalSec;
        // 平均包大小 = 总字节数 / 总包数（若无包则为 0）
        currentAvgPacketSize = (currPackets == 0) ? 0.0 : (double) currBytes / currPackets;

        lastSnapshotTime = now;
    }

    // ========== 查询接口（直接返回缓存，无计算开销）==========
    public double getBandwidthBps() {
        return currentBandwidthBps;
    }

    public double getPacketRatePps() {
        return currentPacketRatePps;
    }

    public double getAvgPacketSize() {
        return currentAvgPacketSize;
    }

    // 原始累加值
    public long getPacketCountSinceLastSnapshot() {
        return cachedPacketCount;
    }

    public long getByteCountSinceLastSnapshot() {
        return cachedByteCount;
    }
}