#!/bin/sh
# disk-guard [--warn PCT] [--crit PCT] [--volume PATH] [--quiet]
#
# Check free space on the data volume and raise a macOS notification when it
# runs low. Meant to run unattended (launchd), but safe to run by hand.
#
# Unlike `disk-reclaim` (which only reports and is read-only), this is the
# *alarm*: it makes low disk visible BEFORE the volume hits ~97% full and
# things start failing. It never deletes anything.
#
# Flags:
#   --warn PCT     warn when free space drops below PCT percent (default 15)
#   --crit PCT     critical when free space drops below PCT percent (default 7)
#   --volume PATH  volume to check (default /System/Volumes/Data)
#   --quiet        no stdout; only notify + log (for launchd)
#
# Exit status: 0 ok, 1 warn, 2 critical. Always logs to
# ~/Library/Logs/disk-reclaim.log so boot snapshots and alarms share a trail.

set -eu

warn_pct=15
crit_pct=7
volume=/System/Volumes/Data
quiet=0

die() { echo "disk-guard: $*" >&2; exit 64; }

while [ $# -gt 0 ]; do
    case "$1" in
        -h|--help) sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'; exit 2 ;;
        --warn)    [ $# -ge 2 ] || die "--warn needs a value"; warn_pct=$2; shift 2 ;;
        --crit)    [ $# -ge 2 ] || die "--crit needs a value"; crit_pct=$2; shift 2 ;;
        --volume)  [ $# -ge 2 ] || die "--volume needs a value"; volume=$2; shift 2 ;;
        --quiet)   quiet=1; shift ;;
        *)         die "unknown arg: $1" ;;
    esac
done

# df -k: portable. Columns: Filesystem 1024-blocks Used Available Capacity ...
# Available is field 4, in KiB. Compute free percent ourselves (Capacity is
# "used %" and rounds oddly on APFS shared containers).
read -r avail_kb total_kb <<EOF
$(df -k "$volume" | awk 'NR==2 {print $4, $2}')
EOF

[ -n "${total_kb:-}" ] && [ "$total_kb" -gt 0 ] || die "could not read df for $volume"

free_pct=$(( avail_kb * 100 / total_kb ))
avail_gb=$(awk -v k="$avail_kb" 'BEGIN { printf "%.1f", k/1048576 }')

log="$HOME/Library/Logs/disk-reclaim.log"
mkdir -p "$(dirname "$log")"
stamp=$(date '+%Y-%m-%d %H:%M:%S %z')

notify() {
    # Best-effort macOS banner; ignore failure (e.g. headless/ssh).
    osascript -e "display notification \"$2\" with title \"$1\" sound name \"Basso\"" \
        >/dev/null 2>&1 || true
}

if [ "$free_pct" -lt "$crit_pct" ]; then
    level=CRITICAL; rc=2
    notify "Disk critically full" "${avail_gb}G free (${free_pct}%) on $volume. Run: disk-reclaim"
elif [ "$free_pct" -lt "$warn_pct" ]; then
    level=WARN; rc=1
    notify "Disk getting full" "${avail_gb}G free (${free_pct}%) on $volume. Run: disk-reclaim"
else
    level=OK; rc=0
fi

echo "=== $stamp (guard) $level: ${avail_gb}G free (${free_pct}%) on $volume ===" >> "$log"

# On WARN/CRIT, append a reclaim snapshot so the log shows what to delete.
if [ "$rc" -ne 0 ]; then
    script_dir=$(cd "$(dirname "$0")" && pwd -P)
    "$script_dir/disk-reclaim" "$HOME" --min 1G >> "$log" 2>&1 || true
fi

[ "$quiet" = 1 ] || echo "$level: ${avail_gb}G free (${free_pct}%) on $volume"
exit "$rc"
