package com.foxx.androidcast.stats;

/*********************************************************************
 * SessionEventJournal.java
 * Created at: Tue 19 May 2026 19:43:06 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 85 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	19a61174daac64926280ac88abb6511c710478a3354bcb479a0bede0017d4232
**********************************************************************/
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * Per-session event log ({@code send} or {@code recv} array only) with ~1 Hz {@code general} rollups.
 */
final class SessionEventJournal {
  private static final long GENERAL_INTERVAL_MS = 1000L;
  private static final int MAX_ENTRIES = 100_000;

  private final long sessionStartMs;
  private final JSONArray events = new JSONArray();
  private long generalAccumulator;
  private long lastGeneralFlushMs;

  SessionEventJournal(long sessionStartMs) {
    this.sessionStartMs = sessionStartMs;
    lastGeneralFlushMs = sessionStartMs;
  }

  synchronized void record(String type, int size) {
    if (type == null || size <= 0) {
      return;
    }
    if (events.length() >= MAX_ENTRIES) {
      return;
    }
    try {
      JSONObject e = new JSONObject();
      e.put("ts", System.currentTimeMillis() - sessionStartMs);
      e.put("type", type);
      e.put("size", size);
      events.put(e);
    } catch (Exception ignored) {
    }
  }

  synchronized void addGeneralBytes(int wireBytes) {
    if (wireBytes > 0) {
      generalAccumulator += wireBytes;
    }
  }

  synchronized void flushGeneralIfDue() {
    long now = System.currentTimeMillis();
    if (now - lastGeneralFlushMs < GENERAL_INTERVAL_MS) {
      return;
    }
    flushGeneral(now);
  }

  synchronized void flushGeneralFinal() {
    flushGeneral(System.currentTimeMillis());
  }

  private void flushGeneral(long now) {
    if (events.length() >= MAX_ENTRIES) {
      generalAccumulator = 0;
      lastGeneralFlushMs = now;
      return;
    }
    try {
      JSONObject e = new JSONObject();
      e.put("ts", now - sessionStartMs);
      e.put("type", SessionStatsEventMapper.GENERAL);
      e.put("size", generalAccumulator);
      events.put(e);
    } catch (Exception ignored) {
    }
    generalAccumulator = 0;
    lastGeneralFlushMs = now;
  }

  synchronized JSONArray copyEvents() {
    return events;
  }
}
