# activate-repo-ruby.sh — pin the target repo's declared Ruby for non-interactive spawns
#
# iOS pod/gem work (yarn setup, native build) reads Ruby from PATH. Under tmux /
# nohup / a cold checkout the PATH is the system Ruby, which does not match the
# repo's .ruby-version and fails `bundle install` / `pod install` with native gem
# build errors. Sourced by the leaves that trigger pods so they run the pinned
# Ruby, mirroring activate-repo-node.sh for Node.
#
# On success sets REPO_RUBY_VERSION / REPO_RUBY_BIN / REPO_RUBY_BIN_DIR /
# REPO_RUBY_PATH_PREFIX and prepends the bin dir to PATH.
#
# Usage:
#   . /path/to/activate-repo-ruby.sh
#   activate_repo_ruby [target-dir]          # 0 pinned; 1 none declared; 2 declared but unresolved
#   activate_repo_ruby_best_effort [dir]     # never fails the caller; warns + teaches on 2

_repo_ruby_matches_req() {
  local req="$1" actual="${2:-}"
  [ -n "$actual" ] || actual="$("$REPO_RUBY_BIN" -e 'print RUBY_VERSION' 2>/dev/null || true)"
  [ -n "$actual" ] || return 1
  [ "$actual" = "$req" ] && return 0
  case "$req" in
    *.*.*) return 1 ;;
    *.*) [[ "$actual" == "$req."* ]] ;;
    *) [[ "$actual" == "$req"* ]] ;;
  esac
}

_repo_ruby_set_from_bin() {
  local candidate="$1"
  [ -n "$candidate" ] && [ -x "$candidate" ] || return 1
  REPO_RUBY_BIN="$candidate"
  REPO_RUBY_BIN_DIR="$(cd "$(dirname "$REPO_RUBY_BIN")" && pwd)"
  REPO_RUBY_PATH_PREFIX="${REPO_RUBY_BIN_DIR}:"
  export PATH="${REPO_RUBY_BIN_DIR}:${PATH}"
  return 0
}

_repo_ruby_try_req() {
  local target="$1" req="$2"
  [ -n "$req" ] || return 1
  REPO_RUBY_VERSION="$req"

  if command -v asdf >/dev/null 2>&1; then
    local asdf_root
    asdf_root="$(asdf where ruby "$req" 2>/dev/null || true)"
    if [ -n "$asdf_root" ] && _repo_ruby_set_from_bin "$asdf_root/bin/ruby" && _repo_ruby_matches_req "$req"; then
      echo "[env] ruby $("$REPO_RUBY_BIN" -e 'print RUBY_VERSION') from .ruby-version/.tool-versions via asdf ($req)" >&2
      return 0
    fi
  fi

  if command -v rbenv >/dev/null 2>&1; then
    local rbenv_root
    rbenv_root="$(rbenv root 2>/dev/null || true)"
    if [ -n "$rbenv_root" ] && _repo_ruby_set_from_bin "$rbenv_root/versions/$req/bin/ruby" && _repo_ruby_matches_req "$req"; then
      echo "[env] ruby $("$REPO_RUBY_BIN" -e 'print RUBY_VERSION') from .ruby-version via rbenv ($req)" >&2
      return 0
    fi
  fi

  if command -v mise >/dev/null 2>&1; then
    local mise_bin
    mise_bin="$(mise x -C "$target" -- which ruby 2>/dev/null || true)"
    if _repo_ruby_set_from_bin "$mise_bin" && _repo_ruby_matches_req "$req"; then
      echo "[env] ruby $("$REPO_RUBY_BIN" -e 'print RUBY_VERSION') from .ruby-version via mise ($req)" >&2
      return 0
    fi
  fi
  return 1
}

activate_repo_ruby() {
  local target="${1:-.}"
  REPO_RUBY_VERSION=""
  REPO_RUBY_BIN=""
  REPO_RUBY_BIN_DIR=""
  REPO_RUBY_PATH_PREFIX=""

  local declared=false req=""
  if [ -f "$target/.ruby-version" ]; then
    declared=true
    req="$(tr -d ' \t\r\n' < "$target/.ruby-version")"
    req="${req#ruby-}"
    _repo_ruby_try_req "$target" "$req" && return 0
  fi
  if [ -z "$req" ] && [ -f "$target/.tool-versions" ]; then
    declared=true
    req="$(awk '/^ruby / {print $2; exit}' "$target/.tool-versions")"
    _repo_ruby_try_req "$target" "$req" && return 0
  fi

  if [ "$declared" != true ]; then
    return 1
  fi

  # Declared already-on-PATH match (e.g. chruby/system already correct).
  local path_ruby
  path_ruby="$(command -v ruby 2>/dev/null || true)"
  if [ -n "$req" ] && _repo_ruby_set_from_bin "$path_ruby" && _repo_ruby_matches_req "$req"; then
    echo "[env] ruby $("$REPO_RUBY_BIN" -e 'print RUBY_VERSION') already on PATH ($req)" >&2
    return 0
  fi

  REPO_RUBY_BIN=""
  REPO_RUBY_BIN_DIR=""
  REPO_RUBY_PATH_PREFIX=""
  return 2
}

# Best-effort: never fails the caller. On a declared-but-unresolved Ruby, warn with
# a teaching hint so a subsequent pod/gem failure is diagnosable (system Ruby).
activate_repo_ruby_best_effort() {
  local target="${1:-.}"
  # Guard the call so a non-zero return (no version / unresolved) never trips the
  # caller's set -e before we can inspect the code.
  local rc=0
  activate_repo_ruby "$target" || rc=$?
  if [ "$rc" -eq 2 ]; then
    echo "[env] repo pins ruby ${REPO_RUBY_VERSION:-?} (.ruby-version/.tool-versions) but no installed manager provided it; using system ruby." >&2
    echo "  Next: install it — asdf install ruby ${REPO_RUBY_VERSION:-<version>}  (or rbenv install) — then re-run, so iOS gems build against the pinned Ruby" >&2
  fi
  return 0
}
