#!/usr/bin/env bash
# Standing RSS sampler — Task 600.
# Reads /proc/meminfo and per-claude.exe /proc/<pid>/status every 30s.
# Appends one structured line per cycle to LOG_PATH.
# Caps log at LOG_MAX_BYTES (default 10485760 = 10MB).

set -euo pipefail

LOG_PATH="${LOG_PATH:-/tmp/rss-sampler.log}"
LOG_MAX_BYTES="${LOG_MAX_BYTES:-10485760}"
INTERVAL="${INTERVAL:-30}"

while true; do
  # Read /proc/meminfo for MemTotal and MemAvailable (in kB)
  mem_total_kb=0
  mem_available_kb=0
  while IFS=': ' read -r key val _unit; do
    case "$key" in
      MemTotal)     mem_total_kb="$val" ;;
      MemAvailable) mem_available_kb="$val" ;;
    esac
  done < /proc/meminfo
  mem_total_mb=$(( mem_total_kb / 1024 ))
  mem_available_mb=$(( mem_available_kb / 1024 ))

  # Find all claude.exe PIDs
  mapfile -t pids < <(pgrep -x "claude.exe" 2>/dev/null || true)
  claude_count="${#pids[@]}"
  aggregate_rss_mb=0
  pid_pairs=""

  for pid in "${pids[@]}"; do
    rss_kb=0
    if [[ -r "/proc/${pid}/status" ]]; then
      rss_kb=$(grep -m1 '^VmRSS:' "/proc/${pid}/status" 2>/dev/null | awk '{print $2}' || echo 0)
    fi
    rss_mb=$(( rss_kb / 1024 ))
    aggregate_rss_mb=$(( aggregate_rss_mb + rss_mb ))
    pid_pairs="${pid_pairs:+$pid_pairs,}${pid}:${rss_mb}"
  done

  ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
  line="${ts}  MemTotalMB=${mem_total_mb} MemAvailableMB=${mem_available_mb}  claude_count=${claude_count}  aggregate_rss_mb=${aggregate_rss_mb}  pids=${pid_pairs:-none}"
  echo "$line" >> "$LOG_PATH"

  # Cap log at LOG_MAX_BYTES: drop oldest half when threshold is exceeded
  if [[ -f "$LOG_PATH" ]]; then
    actual_bytes=$(wc -c < "$LOG_PATH")
    if (( actual_bytes > LOG_MAX_BYTES )); then
      total_lines=$(wc -l < "$LOG_PATH")
      keep_lines=$(( total_lines / 2 ))
      tmp_file="${LOG_PATH}.tmp"
      tail -n "$keep_lines" "$LOG_PATH" > "$tmp_file" && mv "$tmp_file" "$LOG_PATH"
    fi
  fi

  sleep "$INTERVAL"
done
