package com.foxx.androidcast.network.diag;

/**
 * Rolling diagnostic ping RTT samples for overlays and bandwidth hints.
 */
public final class DiagPingMetrics {
    private static final int WINDOW = 16;

    private final long[] rttMs = new long[WINDOW];
    private final long[] seq = new long[WINDOW];
    private int count;
    private int index;
    private long probesSent;
    private long pongsRx;
    private long lastRttMs;
    private long lastSeq;

    public synchronized void recordProbeSent(long seqNum) {
        probesSent++;
        lastSeq = seqNum;
    }

    public synchronized void recordPong(long rtt, long pongSeq) {
        if (rtt <= 0 || rtt > 30_000) {
            return;
        }
        pongsRx++;
        lastRttMs = rtt;
        lastSeq = pongSeq;
        rttMs[index] = rtt;
        seq[index] = pongSeq;
        index = (index + 1) % WINDOW;
        if (count < WINDOW) {
            count++;
        }
    }

    public synchronized Snapshot snapshot() {
        Snapshot s = new Snapshot();
        s.enabled = true;
        s.probesSent = probesSent;
        s.pongsRx = pongsRx;
        s.lastRttMs = (int) lastRttMs;
        s.lastSeq = lastSeq;
        if (count == 0) {
            return s;
        }
        long sum = 0;
        for (int i = 0; i < count; i++) {
            sum += rttMs[i];
        }
        s.avgRttMs = (int) (sum / count);
        return s;
    }

    public synchronized int preferredRttMs(int fallbackRtt) {
        Snapshot s = snapshot();
        if (s.avgRttMs > 0) {
            return s.avgRttMs;
        }
        if (s.lastRttMs > 0) {
            return s.lastRttMs;
        }
        return fallbackRtt;
    }

    public synchronized void reset() {
        count = 0;
        index = 0;
        probesSent = 0;
        pongsRx = 0;
        lastRttMs = 0;
        lastSeq = 0;
    }

    public static final class Snapshot {
        public boolean enabled;
        public long probesSent;
        public long pongsRx;
        public int lastRttMs;
        public int avgRttMs;
        public long lastSeq;

        public static final Snapshot EMPTY = new Snapshot();
    }
}
