#!/usr/bin/env bash
# Stand-in for `git` during pyodide-build.
#
# GitLab Runner leaves GIT_ASKPASS / credential helpers in the environment, so
# `git clone https://github.com/...` prompts for a username and fails with:
#   fatal: could not read Username for 'https://github.com': No such device or address
# pyodide-build clones emscripten-core/emsdk that way. Fetch the same tree as a
# GitHub source tarball over HTTPS instead (the xbuildenv archive already uses
# plain HTTP(S) and succeeds on these runners).
set -euo pipefail

WRAPPER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

find_real_git() {
  if [[ -n "${MOHO_REAL_GIT:-}" && -x "${MOHO_REAL_GIT}" ]]; then
    printf '%s\n' "${MOHO_REAL_GIT}"
    return
  fi
  local candidate
  for candidate in /usr/bin/git /bin/git; do
    if [[ -x "${candidate}" ]]; then
      printf '%s\n' "${candidate}"
      return
    fi
  done
  # Strip this wrapper directory so `command -v git` cannot recurse.
  local cleaned="${PATH}"
  cleaned="${cleaned//${WRAPPER_DIR}:/}"
  cleaned="${cleaned//:${WRAPPER_DIR}/}"
  PATH="${cleaned}" command -v git
}

REAL_GIT="$(find_real_git)"
if [[ -z "${REAL_GIT}" || "${REAL_GIT}" == "${WRAPPER_DIR}/git" ]]; then
  echo "github-git: cannot locate the real git binary" >&2
  exit 127
fi

github_repo_from_url() {
  local url="$1"
  url="${url%.git}"
  url="${url%/}"
  case "${url}" in
    https://github.com/*) url="${url#https://github.com/}" ;;
    http://github.com/*) url="${url#http://github.com/}" ;;
    git://github.com/*) url="${url#git://github.com/}" ;;
    git@github.com:*) url="${url#git@github.com:}" ;;
    ssh://git@github.com/*) url="${url#ssh://git@github.com/}" ;;
    *) return 1 ;;
  esac
  local owner="${url%%/*}"
  local rest="${url#*/}"
  printf '%s/%s\n' "${owner}" "${rest%%/*}"
}

download_url() {
  local url="$1"
  local dest="$2"
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL --retry 3 --retry-delay 2 -A "moho-framework-ci" -o "${dest}" "${url}"
    return
  fi
  if command -v wget >/dev/null 2>&1; then
    wget -q -O "${dest}" "${url}"
    return
  fi
  local py
  if command -v python3 >/dev/null 2>&1; then
    py=python3
  elif command -v python >/dev/null 2>&1; then
    py=python
  else
    echo "github-git: need curl, wget, or python to download ${url}" >&2
    return 1
  fi
  "${py}" - "${url}" "${dest}" <<'PY'
import sys
import urllib.request

url, dest = sys.argv[1], sys.argv[2]
req = urllib.request.Request(url, headers={"User-Agent": "moho-framework-ci"})
with urllib.request.urlopen(req, timeout=120) as resp, open(dest, "wb") as out:
    while True:
        chunk = resp.read(1024 * 256)
        if not chunk:
            break
        out.write(chunk)
PY
}

clone_github_tarball() {
  local url="$1"
  local dest="$2"
  local repo
  repo="$(github_repo_from_url "${url}")" || return 1

  # Subshell so the EXIT trap cannot leak into later git commands.
  (
    set -euo pipefail
    tmp="$(mktemp -d)"
    trap 'rm -rf "${tmp}"' EXIT

    echo "github-git: fetching ${repo} as a source tarball into ${dest}" >&2
    archive="${tmp}/src.tar.gz"
    ok=0
    for branch in main master; do
      if download_url "https://codeload.github.com/${repo}/tar.gz/refs/heads/${branch}" "${archive}" \
        || download_url "https://github.com/${repo}/archive/refs/heads/${branch}.tar.gz" "${archive}"; then
        ok=1
        break
      fi
    done
    if [[ "${ok}" -ne 1 ]]; then
      if download_url "https://github.com/${repo}/archive/HEAD.tar.gz" "${archive}"; then
        ok=1
      fi
    fi
    if [[ "${ok}" -ne 1 ]]; then
      echo "github-git: tarball download failed for ${repo}" >&2
      exit 1
    fi

    mkdir -p "${dest}"
    tar -xzf "${archive}" -C "${dest}" --strip-components=1
    chmod +x "${dest}/emsdk" "${dest}/emsdk.py" 2>/dev/null || true
  )
}

run_real_git() {
  # Do not inherit GitLab's askpass helper on the fallback path either.
  env -u GIT_ASKPASS -u SSH_ASKPASS GIT_TERMINAL_PROMPT=0 "${REAL_GIT}" "$@"
}

if [[ "${1:-}" == "clone" ]]; then
  github_url=""
  for arg in "$@"; do
    case "${arg}" in
      https://github.com/*|http://github.com/*|git://github.com/*|git@github.com:*|ssh://git@github.com/*)
        github_url="${arg}"
        ;;
    esac
  done
  dest="${@: -1}"
  if [[ -n "${github_url}" && "${dest}" != "${github_url}" && "${dest}" != -* ]]; then
    if clone_github_tarball "${github_url}" "${dest}"; then
      exit 0
    fi
    echo "github-git: falling back to real git clone" >&2
  fi
fi

run_real_git "$@"
