#!/usr/bin/env bash
# autopilot-activation.sh  -  which repos may this machine pick work up from.
#
# The answer is NEVER "all of them" and never "whatever has the label". Measured
# on one machine: 66 repos grant push, and a good half belong to other people -
# a colleague's backend, someone's side project. A label is a filter, not a gate:
# anyone able to open an issue in a repo you happen to have push on could put
# `agent-queue` on it. The gate is this picker, and the picker is per machine.
#
# Two lists come out, and the difference matters:
#
#   eligible    push rights AND a checkout on this machine
#   unavailable push rights, no checkout - LISTED, with that as the reason
#
# The second list is printed rather than dropped. Silently hiding 40 repos from a
# 66-repo answer looks exactly like a permissions problem, and the user then goes
# looking for a token fault that does not exist.
#
# Usage:
#   bash autopilot-activation.sh list            # TSV: state, nameWithOwner, localPath
#   bash autopilot-activation.sh list --json
#   . autopilot-activation.sh; ma_ap_local_path <owner/repo>
#
# Exit: 0 on success (including an empty list), 2 on usage, 3 when gh cannot answer.

set -uo pipefail

# Repo roots to search for checkouts. $HOME's immediate children covers the
# normal layout; MA_AUTOPILOT_REPO_ROOTS overrides it for tests and for anyone
# who keeps checkouts somewhere else.
MA_AP_ROOTS="${MA_AUTOPILOT_REPO_ROOTS:-$HOME}"

# owner/repo for a checkout, read from its origin remote. Both URL forms, and a
# trailing .git is stripped - `git@github.com:o/r.git` and
# `https://github.com/o/r` are the same repo and a picker that treats them as
# two shows the user a duplicate they cannot explain.
ma_ap_remote_slug() {
  local dir="$1" url
  url=$(git -C "$dir" remote get-url origin 2>/dev/null) || return 1
  url="${url%.git}"
  case "$url" in
    *github.com[:/]*) printf '%s\n' "${url##*github.com[:/]}" ;;
    *) return 1 ;;
  esac
}

# Every checkout under the roots, as `slug<TAB>path`. One pass, so the lookup
# below is a grep rather than a walk per repo.
ma_ap_checkout_index() {
  local root d slug
  for root in $MA_AP_ROOTS; do
    [ -d "$root" ] || continue
    for d in "$root"/*/; do
      [ -d "$d/.git" ] || continue
      slug=$(ma_ap_remote_slug "${d%/}") || continue
      printf '%s\t%s\n' "$slug" "${d%/}"
    done
  done
}

ma_ap_local_path() { # $1 = owner/repo
  ma_ap_checkout_index | awk -F'\t' -v s="$1" 'tolower($1)==tolower(s){print $2; exit}'
}

# Repos the authenticated account may push to.
#
# The query string form is deliberate: `gh api user/repos --field affiliation=...`
# sends the value as a BODY field on a GET, which this endpoint ignores - it
# answers with the default affiliation and the caller never learns the filter did
# not apply. Measured: the --field form returned 0 rows here, the query string
# form returned 66.
ma_ap_writable_repos() {
  gh api "user/repos?affiliation=owner,collaborator,organization_member&per_page=100" \
    --paginate -q '.[] | select(.permissions.push == true) | .full_name' 2>/dev/null
}

ma_ap_list() {
  local json="${1:-}" slug path index
  index=$(ma_ap_checkout_index)
  local repos
  repos=$(ma_ap_writable_repos)
  if [ -z "$repos" ]; then
    echo "autopilot-activation: gh returned no writable repos - check 'gh auth status'" >&2
    return 3
  fi

  local first=1
  [ "$json" = "--json" ] && printf '['
  while IFS= read -r slug; do
    [ -n "$slug" ] || continue
    path=$(printf '%s\n' "$index" | awk -F'\t' -v s="$slug" 'tolower($1)==tolower(s){print $2; exit}')
    local state="eligible"
    [ -z "$path" ] && state="unavailable"
    if [ "$json" = "--json" ]; then
      [ "$first" -eq 0 ] && printf ','
      first=0
      printf '{"state":"%s","nameWithOwner":"%s","localPath":"%s"}' "$state" "$slug" "$path"
    else
      printf '%s\t%s\t%s\n' "$state" "$slug" "$path"
    fi
  done <<EOF
$repos
EOF
  [ "$json" = "--json" ] && printf ']\n'
  return 0
}

if [ "${BASH_SOURCE[0]:-$0}" = "$0" ]; then
  case "${1:-}" in
    list) ma_ap_list "${2:-}" ;;
    "" | -h | --help) grep -E '^#( |$)' "$0" | sed -E 's/^# ?//' ;;
    *)
      echo "autopilot-activation: unknown command ${1}" >&2
      exit 2
      ;;
  esac
fi
