#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
# varuna-inotify-check — inotify watch diagnostic helper for Varuna
#
# Usage: /usr/share/varuna/bin/varuna-inotify-check [--json]
#
# Shows current inotify kernel limits, per-user watch usage, top watch
# consumers, and advises whether limits need raising for Varuna.
#
# Installed to /usr/share/varuna/bin/ by the varuna .deb package.

set -euo pipefail

JSON_MODE=false
if [ "${1:-}" = "--json" ]; then
  JSON_MODE=true
fi

# ── Read kernel limits ──────────────────────────────────────────────────
MAX_WATCHES="$(cat /proc/sys/fs/inotify/max_user_watches 2>/dev/null || echo 0)"
MAX_INSTANCES="$(cat /proc/sys/fs/inotify/max_user_instances 2>/dev/null || echo 0)"
MAX_QUEUED="$(cat /proc/sys/fs/inotify/max_queued_events 2>/dev/null || echo 0)"

# ── Count total inotify watches in use (system-wide) ───────────────────
# /proc/*/fdinfo/* contains inotify info; each "inotify wd:" line is one watch.
TOTAL_WATCHES=0
if [ -r /proc/1/fdinfo ]; then
  TOTAL_WATCHES="$(grep -r 'inotify wd:' /proc/*/fdinfo/* 2>/dev/null | wc -l || echo 0)"
fi

# ── Identify top consumers ──────────────────────────────────────────────
declare -A PID_WATCHES
if [ -r /proc/1/fdinfo ]; then
  while IFS= read -r line; do
    pid="${line%%/*}"
    pid="${pid##/proc/}"
    PID_WATCHES["${pid}"]=$(( ${PID_WATCHES["${pid}"]:-0} + 1 ))
  done < <(grep -rl 'inotify wd:' /proc/*/fdinfo/ 2>/dev/null || true)
fi

# ── Compute usage percentage ────────────────────────────────────────────
USAGE_PCT=0
if [ "${MAX_WATCHES}" -gt 0 ]; then
  USAGE_PCT=$(( TOTAL_WATCHES * 100 / MAX_WATCHES ))
fi

# ── Determine advisory status ───────────────────────────────────────────
STATUS="ok"
ADVICE=""
if [ "${USAGE_PCT}" -ge 90 ]; then
  STATUS="critical"
  ADVICE="inotify watches are >90% exhausted. Varuna will fail with ENOSPC. Install /etc/sysctl.d/99-varuna-inotify.conf immediately."
elif [ "${USAGE_PCT}" -ge 70 ]; then
  STATUS="warning"
  ADVICE="inotify watches are >70% utilized. Consider raising limits before running Varuna."
elif [ "${MAX_WATCHES}" -lt 1048576 ]; then
  STATUS="suboptimal"
  ADVICE="Limits below Varuna recommended values. Install /etc/sysctl.d/99-varuna-inotify.conf for best results."
fi

# ── Output ──────────────────────────────────────────────────────────────
if [ "${JSON_MODE}" = "true" ]; then
  echo "{"
  echo "  \"max_user_watches\": ${MAX_WATCHES},"
  echo "  \"max_user_instances\": ${MAX_INSTANCES},"
  echo "  \"max_queued_events\": ${MAX_QUEUED},"
  echo "  \"total_watches_in_use\": ${TOTAL_WATCHES},"
  echo "  \"usage_pct\": ${USAGE_PCT},"
  echo "  \"status\": \"${STATUS}\","
  echo "  \"advice\": \"${ADVICE}\""
  echo "}"
else
  echo "=== Varuna inotify Diagnostic ==="
  echo ""
  echo "Kernel limits:"
  echo "  fs.inotify.max_user_watches   = ${MAX_WATCHES}"
  echo "  fs.inotify.max_user_instances = ${MAX_INSTANCES}"
  echo "  fs.inotify.max_queued_events  = ${MAX_QUEUED}"
  echo ""
  echo "Current usage:"
  echo "  Total watches in use (system): ${TOTAL_WATCHES} / ${MAX_WATCHES} (${USAGE_PCT}%)"
  echo ""

  if [ "${#PID_WATCHES[@]}" -gt 0 ]; then
    echo "Top watch consumers (PID: count: process):"
    for pid in "${!PID_WATCHES[@]}"; do
      echo "  ${PID_WATCHES[$pid]} ${pid}"
    done | sort -rn | head -10 | while read -r count pid; do
      comm="$(cat /proc/"${pid}"/comm 2>/dev/null || echo unknown)"
      echo "  PID ${pid}: ${count} watches  [${comm}]"
    done
    echo ""
  fi

  echo "Status: ${STATUS}"
  if [ -n "${ADVICE}" ]; then
    echo "Advisory: ${ADVICE}"
    echo ""
    echo "Quick fix:"
    echo "  sudo cp /usr/share/varuna/inotify-tuning.conf.example \\"
    echo "       /etc/sysctl.d/99-varuna-inotify.conf"
    echo "  sudo sysctl --system"
  else
    echo "inotify limits look healthy for Varuna."
  fi
fi
