#!/usr/bin/env bash
# Buildbox disk admission at the 15 GiB red floor. Probes every unique filesystem
# that will receive agent-heavy writes; refuses when any probe is unknown or below
# floor. Ambient overrides may only raise the floor, never lower or redirect probes.
set -euo pipefail

BUILDBOX_DISK_FLOOR_BYTES=$((15 * 1024 * 1024 * 1024))

buildbox_disk_floor_bytes() {
  local raw parsed
  raw="${BUILDBOX_DISK_MIN_FREE_BYTES:-}"
  if [ -n "$raw" ]; then
    if parsed=$((raw)) 2>/dev/null; then
      if [ "$parsed" -lt "$BUILDBOX_DISK_FLOOR_BYTES" ]; then
        printf '%s\n' "$BUILDBOX_DISK_FLOOR_BYTES"
        return 0
      fi
      printf '%s\n' "$parsed"
      return 0
    fi
  fi
  raw="${BUILDBOX_DISK_MIN_FREE_GIB:-}"
  if [ -n "$raw" ]; then
    if parsed=$((raw)) 2>/dev/null; then
      if [ "$parsed" -lt 15 ]; then
        printf '%s\n' "$BUILDBOX_DISK_FLOOR_BYTES"
        return 0
      fi
      printf '%s\n' $((parsed * 1024 * 1024 * 1024))
      return 0
    fi
  fi
  printf '%s\n' "$BUILDBOX_DISK_FLOOR_BYTES"
}

# Nearest existing ancestor for a destination that may not exist yet.
buildbox_resolve_probe_path() {
  local path="$1" probe
  if [ -e "$path" ]; then
    realpath -- "$path"
    return 0
  fi
  probe="$path"
  while [ ! -e "$probe" ]; do
    [ "$probe" = / ] && return 1
    probe="$(dirname "$probe")"
  done
  realpath -- "$probe"
}

# Prints one probe path per line; returns 1 when any anchor is unknown.
buildbox_unique_probe_paths() {
  local dest path dev seen=()
  for dest in "$@"; do
    [ -n "$dest" ] || continue
    if ! path="$(buildbox_resolve_probe_path "$dest")"; then
      return 1
    fi
    dev="$(stat -c %d "$path")"
    case " ${seen[*]} " in
      *" $dev "*) continue ;;
    esac
    seen+=("$dev")
    printf '%s\n' "$path"
  done
}

buildbox_disk_free_bytes() {
  local target="$1" avail
  avail="$(df -B1 --output=avail "$target" 2>/dev/null | tail -1 | tr -dc '0-9')" || return 1
  [ -n "$avail" ] || return 1
  printf '%s\n' "$avail"
}

# Emits actionable errors to stderr; returns 0 when admitted, 1 when refused.
buildbox_disk_admit() {
  local host="${1:-$(hostname -s 2>/dev/null || hostname)}"
  shift
  local floor paths path free min="$BUILDBOX_DISK_FLOOR_BYTES"
  floor="$(buildbox_disk_floor_bytes)"
  [ "$floor" -ge "$min" ] || floor="$min"
  if ! paths="$(buildbox_unique_probe_paths "$@")"; then
    printf 'buildbox disk admission refused on %s: cannot resolve probe path for destination (required %s GiB)\n' \
      "$host" "$((floor / 1024 / 1024 / 1024))" >&2
    return 1
  fi
  min="$floor"
  while IFS= read -r path; do
    [ -n "$path" ] || continue
    if ! free="$(buildbox_disk_free_bytes "$path")"; then
      printf 'buildbox disk admission refused on %s: mount=%s free=unknown required=%s bytes\n' \
        "$host" "$path" "$floor" >&2
      return 1
    fi
    if [ "$free" -lt "$floor" ]; then
      printf 'buildbox disk admission refused on %s: mount=%s free=%s bytes required=%s bytes\n' \
        "$host" "$path" "$free" "$floor" >&2
      return 1
    fi
  done <<<"$paths"
  return 0
}

buildbox_disk_admit_or_die() {
  buildbox_disk_admit "$@" || exit 75
}
