#!/bin/sh
[ -d "$HOME/.rb/jobs" ] && find "$HOME/.rb/jobs" -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} + 2>/dev/null
if command -v podman >/dev/null 2>&1; then
  stuck=$(podman ps -q --filter until=24h 2>/dev/null)
  if [ -n "$stuck" ]; then
    n=$(printf '%s\n' $stuck | xargs -r podman stop -t 10 2>/dev/null | grep -c .)
    [ "${n:-0}" -gt 0 ] && echo "gc-podman-stuck ${n}"
  fi
  pods=$(for s in exited stopped created; do podman pod ls --filter until=24h --filter status=$s -q 2>/dev/null; done | sort -u)
  if [ -n "$pods" ]; then
    n=$(printf '%s\n' $pods | xargs -r podman pod rm 2>/dev/null | grep -c .)
    [ "${n:-0}" -gt 0 ] && echo "gc-podman-pods ${n}"
  fi
  n=$(podman container prune -f --filter until=24h 2>/dev/null | grep -c .); [ "${n:-0}" -gt 0 ] && echo "gc-podman-containers ${n}"
  n=$(podman volume prune -f --filter until=24h 2>/dev/null | grep -c .); [ "${n:-0}" -gt 0 ] && echo "gc-podman-volumes ${n}"
  n=$(podman image prune -af --filter until=168h 2>/dev/null | grep -c .); [ "${n:-0}" -gt 0 ] && echo "gc-podman-images ${n}"
fi
if command -v pnpm >/dev/null 2>&1; then
  pnpm store prune >/dev/null 2>&1 && echo "gc-pnpm-store"
fi
set -u
root="/home/user/builds"
now=$(date +%s)
cd "$root" 2>/dev/null || exit 0
busy=""
units=$(systemctl --user list-units --state=active --no-legend 'rb-*.service' 2>/dev/null) || {
  echo "gc-busy-probe-failed systemctl" >&2
  exit 1
}
for unit in $(printf '%s
' "$units" | awk '{print $1}'); do
  id="${unit#rb-}"; id="${id%.service}"
  meta="$HOME/.rb/jobs/$id/meta.json"
  [ -f "$meta" ] || continue
  busy="$busy$(grep -o '"mirror":"[^"]*"' "$meta" | head -1 | cut -d'"' -f4)
"
done
command -v podman >/dev/null 2>&1 || {
  echo "gc-busy-probe-failed podman-missing" >&2
  exit 1
}
seats=$(podman ps -a --filter 'name=^harness-seat-' --format '{{.Names}}' 2>/dev/null) || {
  echo "gc-busy-probe-failed podman-list" >&2
  exit 1
}
for seat in $seats; do
  mounts=$(podman inspect --format '{{range .Mounts}}{{println .Source}}{{end}}' "$seat" 2>/dev/null) || {
    echo "gc-busy-probe-failed podman-inspect:$seat" >&2
    exit 1
  }
  busy="$busy$mounts
"
done
for d in */; do
  d="${d%/}"
  [ -d "$d" ] || continue
  [ "$d" = ".repos" ] && continue
  if [ -f "$d/.rb-epoch" ]; then
    [ $(( now - $(stat -c %Y "$d/.rb-epoch") )) -gt $(( 7 * 86400 )) ] && rm -rf -- "$d" && echo "gc-stale $d"
  else
    [ $(( now - $(stat -c %Y "$d") )) -gt 86400 ] && rm -rf -- "$d" && echo "gc-unmarked $d"
  fi
done
if [ -d .repos ]; then
  for r in .repos/*/; do
    r="${r%/}"
    [ -d "$r" ] || continue
    [ $(( now - $(stat -c %Y "$r") )) -gt $(( 30 * 86400 )) ] && rm -rf -- "$r" && echo "gc-repo $r"
  done
fi
idle() {
  case "$busy" in *"$root/$1
"*) return 1 ;; esac
  stamp="$1"; [ -f "$1/.rb-epoch" ] && stamp="$1/.rb-epoch"
  [ $(( now - $(stat -c %Y "$stamp") )) -gt $(( 60 * 60 )) ]
}
failed=""
while [ "$(df -BG --output=avail "$root" | tail -1 | tr -dc 0-9)" -lt 15 ]; do
  oldest=""; oldest_ts=""; kind=""
  for d in */; do
    d="${d%/}"
    [ -d "$d" ] && [ "$d" != ".repos" ] && [ -f "$d/.rb-epoch" ] || continue
    idle "$d" || continue
    case "$failed" in *"$d"$'\n'*) continue ;; esac
    ts=$(stat -c %Y "$d/.rb-epoch")
    if [ -z "$oldest_ts" ] || [ "$ts" -lt "$oldest_ts" ]; then oldest="$d"; oldest_ts="$ts"; kind="mirror"; fi
  done
  if [ -z "$oldest" ]; then
    for r in .repos/*/; do
      r="${r%/}"
      [ -d "$r" ] || continue
      idle "$r" || continue
      case "$failed" in *"$r"$'\n'*) continue ;; esac
      ts=$(stat -c %Y "$r")
      if [ -z "$oldest_ts" ] || [ "$ts" -lt "$oldest_ts" ]; then oldest="$r"; oldest_ts="$ts"; kind="repo"; fi
    done
  fi
  [ -n "$oldest" ] || break
  if rm -rf -- "$oldest"; then
    if [ "$kind" = "repo" ]; then echo "gc-repo-floor $oldest"; else echo "gc-floor $oldest"; fi
  else
    echo "gc-floor-failed $oldest" >&2
    failed="$failed$oldest"$'\n'
  fi
done
avail=$(df -BG --output=avail "$root" | tail -1 | tr -dc 0-9)
if [ "$avail" -lt 15 ]; then
  echo "gc-floor-unmet avail=${avail}GB need=15GB" >&2
  exit 1
fi
exit 0
