#!/usr/bin/env bash
# clean-gone: List local branches whose remote tracking branch is gone.
# Outputs one branch name per line, or nothing if none found.

set -euo pipefail

# Ensure we have current remote state
git fetch --prune 2>/dev/null

# Find branches marked [gone] in tracking info.
# `git branch -vv` output format:
#   * main           abc1234 [origin/main] commit msg
#   + feature-x      def5678 [origin/feature-x: gone] commit msg
#     old-branch     789abcd [origin/old-branch: gone] commit msg
#
# The leading column can be: ' ' (normal), '*' (current), '+' (worktree).
# We match lines containing ": gone]" to find branches whose remote is deleted.

gone_branches=()

while IFS= read -r line; do
  # Skip the currently checked-out branch (marked with '*').
  # git branch -D cannot delete the active branch, and attempting it
  # would halt cleanup before other stale branches are processed.
  if [[ "$line" =~ ^\* ]]; then
    continue
  fi

  # Strip the leading marker character(s) and whitespace
  # The branch name is the first non-whitespace token after the marker
  branch_name=$(echo "$line" | sed 's/^[+* ]*//' | awk '{print $1}')

  # Validate: skip empty, skip if it looks like a hash or flag, skip HEAD
  if [[ -z "$branch_name" ]] || [[ "$branch_name" =~ ^[0-9a-f]{7,}$ ]] || [[ "$branch_name" == "HEAD" ]]; then
    continue
  fi

  gone_branches+=("$branch_name")
done < <(git branch -vv 2>/dev/null | grep ': gone]')

if [[ ${#gone_branches[@]} -eq 0 ]]; then
  echo "__NONE__"
  exit 0
fi

for branch in "${gone_branches[@]}"; do
  echo "$branch"
done
