#!/bin/sh
set -eu

disk_path=${SM_DISK_PATH:-/}
warn_used=${SM_DISK_WARN_USED_PCT:-75}
crit_used=${SM_DISK_CRIT_USED_PCT:-85}
warn_free_gib=${SM_DISK_WARN_FREE_GIB:-100}
crit_free_gib=${SM_DISK_CRIT_FREE_GIB:-50}
maintain_cooldown=${SM_DISK_MAINTAIN_COOLDOWN_SECONDS:-21600}
escalation_drop_gib=${SM_DISK_ESCALATION_DROP_GIB:-10}
maintain_bin=${SM_DISK_MAINTAIN_BIN:-/usr/local/bin/system-monitor-disk-maintain}
state_dir=${XDG_STATE_HOME:-$HOME/.local/state}/system-monitor
state_path=$state_dir/disk-check.state
maintain_stamp=$state_dir/maintenance.last

probe() {
  output=$(df -Pk "$disk_path") || {
    logger -t system-monitor "disk probe failed path=$disk_path"
    exit 75
  }
  stats=$(printf '%s\n' "$output" | awk 'NR == 2 { gsub("%", "", $5); print $4, $5 }')
  free_kib=${stats%% *}
  used_pct=${stats##* }
  case "$free_kib:$used_pct" in
    *[!0-9:]* | :*)
      logger -t system-monitor "disk probe malformed path=$disk_path"
      exit 75
      ;;
  esac
  free_gib=$((free_kib / 1024 / 1024))
  tier=
  if [ "$used_pct" -ge "$crit_used" ] || [ "$free_gib" -lt "$crit_free_gib" ]; then
    tier=critical
  elif [ "$used_pct" -ge "$warn_used" ] || [ "$free_gib" -lt "$warn_free_gib" ]; then
    tier=warning
  fi
}

probe
printf 'path=%s used_pct=%s free_gib=%s tier=%s\n' "$disk_path" "$used_pct" "$free_gib" "${tier:-ok}"

previous_tier=
previous_free=
if [ -r "$state_path" ]; then
  read -r previous_tier previous_free < "$state_path" || true
fi
# Field 2 was an epoch timestamp in the pre-maintenance state format.
case "$previous_free" in
  '' | *[!0-9]*) previous_free=$free_gib ;;
  *) if [ "$previous_free" -gt 100000 ]; then previous_free=$free_gib; fi ;;
esac

# Remediate before deciding whether anything is worth saying.
maintain_summary=
if [ -n "$tier" ] && [ -x "$maintain_bin" ]; then
  last_maintain=0
  if [ -r "$maintain_stamp" ]; then
    read -r last_maintain < "$maintain_stamp" || true
  fi
  now=$(date +%s)
  if [ "$((now - last_maintain))" -ge "$maintain_cooldown" ]; then
    maintain_summary=$("$maintain_bin" 2>&1 | tail -1) || true
    logger -t system-monitor "disk maintenance: $maintain_summary"
    probe
  fi
fi

notify=false
if [ "${tier:-ok}" != "${previous_tier:-ok}" ]; then
  notify=true
elif [ "$tier" = critical ] && [ "$free_gib" -le "$((previous_free - escalation_drop_gib))" ]; then
  notify=true
fi

if [ "$notify" = true ] && [ -n "$tier" ]; then
  message="Disk $tier: ${used_pct}% used, ${free_gib} GiB free"
  if [ -n "$maintain_summary" ]; then message="$message
Auto-cleanup: $maintain_summary"; fi
  logger -p "user.$([ "$tier" = critical ] && printf crit || printf warning)" -t system-monitor "$message"
  if command -v notify-send >/dev/null 2>&1; then
    notify-send -u "$([ "$tier" = critical ] && printf critical || printf normal)" "System Monitor" "$message"
  fi
elif [ "$notify" = true ]; then
  message="Disk recovered: ${used_pct}% used, ${free_gib} GiB free"
  logger -p user.notice -t system-monitor "$message"
  if command -v notify-send >/dev/null 2>&1; then
    notify-send -u low "System Monitor" "$message"
  fi
fi

mkdir -p "$state_dir"
state_tmp=$state_path.$$
if [ "$notify" = true ]; then
  printf '%s %s\n' "${tier:-ok}" "$free_gib" > "$state_tmp"
else
  printf '%s %s\n' "${tier:-ok}" "$previous_free" > "$state_tmp"
fi
mv -f "$state_tmp" "$state_path"
