#!/usr/bin/env bash
# gc-report.sh  -  the --report and --only options gc-tmp.sh, gc-refs.sh and
# gc-worktrees.sh share, in the shape gc-abandoned.sh already writes.
#
#   --report <file>  append one JSON line per candidate:
#                    {kind, path, action, reason, sizeKb}
#                    action is would-remove in a dry run, removed or
#                    remove-failed under --yes. Needs jq.
#   --only <file>    consider only the paths listed in <file>, one per line,
#                    compared by real path. A client previews with --report,
#                    then applies with --only over exactly what it showed, so a
#                    candidate that appeared in between is not removed unseen.
#
# Sourced, never run. Bash 3.2.

GC_REPORT_FILE=""
GC_ONLY_FILE=""
GC_ONLY_LIST=""

# Real path of a file or directory that exists; the path itself otherwise.
gc_real() {
  if [ -d "$1" ]; then
    (cd "$1" 2>/dev/null && pwd -P) || printf '%s\n' "$1"
  elif [ -e "$1" ]; then
    printf '%s/%s\n' "$(cd "$(dirname "$1")" 2>/dev/null && pwd -P)" "$(basename "$1")"
  else
    printf '%s\n' "$1"
  fi
}

# $1 = --report file (may be empty), $2 = --only file (may be empty), $3 = caller name.
gc_report_init() {
  GC_REPORT_FILE="$1"
  GC_ONLY_FILE="$2"
  if [ -n "$GC_REPORT_FILE" ] && ! command -v jq >/dev/null 2>&1; then
    echo "$3: --report needs jq" >&2
    return 2
  fi
  if [ -n "$GC_ONLY_FILE" ]; then
    [ -f "$GC_ONLY_FILE" ] || { echo "$3: --only file not found: $GC_ONLY_FILE" >&2; return 2; }
    local p
    while IFS= read -r p || [ -n "$p" ]; do
      [ -n "$p" ] || continue
      GC_ONLY_LIST="$GC_ONLY_LIST
$(gc_real "$p")"
    done < "$GC_ONLY_FILE"
  fi
  return 0
}

# True when no --only list was given, or when $1 is on it.
gc_listed() {
  [ -z "$GC_ONLY_FILE" ] && return 0
  printf '%s\n' "$GC_ONLY_LIST" | grep -qxF "$(gc_real "$1")"
}

# $1 kind, $2 path, $3 action, $4 reason, $5 size in KB
gc_emit() {
  [ -n "$GC_REPORT_FILE" ] || return 0
  jq -nc --arg kind "$1" --arg path "$(gc_real "$2")" --arg action "$3" --arg reason "$4" \
    --argjson kb "${5:-0}" \
    '{kind:$kind, path:$path, action:$action, reason:$reason, sizeKb:$kb}' \
    >> "$GC_REPORT_FILE" 2>/dev/null || true
}
