# Shared progress machinery for the hooks. `pre-commit` and `pre-push` load it
# with `. "$ROOT/.husky/lib.sh"` — husky only runs the files git invokes by hook
# name, so this one never executes on its own.
#
# Why it exists: lint and the test suite take tens of seconds, and until they
# print something the terminal looks frozen rather than busy. So every step is
# written BEFORE the work starts, with no trailing newline
# ("[2/3] typecheck … "), and the same line gains "ok 12.0s" when it finishes.
# No background spinner: a hook has to stay simple and stay readable in a CI log.

fail() { printf '\n' >&2; echo "✖ $1" >&2; exit 1; }

# Timing is optional. Where `date +%s%3N` or `awk` is missing, TIMER=0 and the
# steps print a bare "ok". A missing clock must never gate a commit.
TIMER=0
if command -v awk >/dev/null 2>&1; then
  case "$(date +%s%3N 2>/dev/null)" in
    ''|*[!0-9]*) ;;
    *) TIMER=1 ;;
  esac
fi

now_ms() { [ "$TIMER" = 1 ] && date +%s%3N || echo 0; }
since()  { [ "$TIMER" = 1 ] && awk -v a="$1" -v b="$(now_ms)" 'BEGIN{printf " %.1fs",(b-a)/1000}'; }

# Step counter. The calling hook must set TOTAL before the first `step`.
TOTAL=0
STEP=0
STEP_T0=0

step()      { STEP=$((STEP + 1)); STEP_T0="$(now_ms)"; printf '[%d/%d] %s … ' "$STEP" "$TOTAL" "$1"; }
step_ok()   { printf 'ok%s\n' "$(since "$STEP_T0")"; }
step_skip() { printf '⚠ skipped (%s)\n' "$1"; }

count() { echo "$1" | grep -c . ; }
