#!/bin/ash
#
# Point submodule fetches at Gitea mirrors without changing committed .gitmodules.
# Rewrites are stored in .git/config (per clone) or optional --global insteadOf rules.
#
# Usage (inside android_cast checkout, or pass repo path):
#   ./gitea_submodule_local_rewrite.sh                 # print commands
#   ./gitea_submodule_local_rewrite.sh --apply         # write .git/config
#   ./gitea_submodule_local_rewrite.sh --apply --global # url.insteadOf in ~/.gitconfig
#   ./gitea_submodule_local_rewrite.sh .gitmodules     # read paths/URLs from file
#
set -eu

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
GITEA_OWNER="${GITEA_OWNER:-AndroidCast}"
GITEA_ROOT_URL="${GITEA_ROOT_URL:-https://apps.f0xx.org/app/androidcast_project/git}"
GITEA_SUBMODULES_CONF="${GITEA_SUBMODULES_CONF:-$SCRIPT_DIR/submodules.defaults.conf}"

log() { printf '[gitea-submodule-rewrite] %s\n' "$*"; }
die() { printf '[gitea-submodule-rewrite] ERROR: %s\n' "$*" >&2; exit 1; }

gitea_public_repo_url_for() {
  _owner="$1"
  _repo="$2"
  _root="$GITEA_ROOT_URL"
  case "$_root" in
    */) _root="${_root%/}" ;;
  esac
  printf '%s/%s/%s.git' "$_root" "$_owner" "$_repo"
}

parse_gitmodules_file() {
  _file="$1"
  [ -r "$_file" ] || return 1
  awk '
    function trim(s) {
      sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s)
      return s
    }
    /^[ \t]*path[ \t]*=/ {
      p = $0; sub(/^[^=]*=/, "", p); path = trim(p)
      n = path; sub(".*/", "", n)
      next
    }
    /^[ \t]*url[ \t]*=/ {
      u = $0; sub(/^[^=]*=/, "", u); url = trim(u)
      next
    }
    /^\[/ {
      if (path != "" && url != "" && n != "") print n "|" url "|" path
      path = ""; url = ""; n = ""
    }
    END {
      if (path != "" && url != "" && n != "") print n "|" url "|" path
    }
  ' "$_file"
}

load_entries() {
  _gitmodules="${1:-}"
  if [ -n "$_gitmodules" ] && [ -r "$_gitmodules" ]; then
    log "reading $_gitmodules" >&2
    parse_gitmodules_file "$_gitmodules"
    return 0
  fi
  if [ -r "$GITEA_SUBMODULES_CONF" ]; then
    log "reading $GITEA_SUBMODULES_CONF" >&2
    grep -v '^[[:space:]]*#' "$GITEA_SUBMODULES_CONF" | grep -v '^[[:space:]]*$' \
      | awk -F'|' 'NF >= 3 { print $1 "|" $2 "|" $3 }'
    return 0
  fi
  return 1
}

_apply=0
_global=0
_gitmodules_arg=""
_repo_dir=""

while [ $# -gt 0 ]; do
  case "$1" in
    -h|--help)
      sed -n '2,14p' "$0"
      exit 0
      ;;
    --apply) _apply=1; shift ;;
    --global) _global=1; shift ;;
    -*)
      die "unknown option: $1"
      ;;
    *)
      if [ -r "$1" ] || [ -f "$1" ]; then
        _gitmodules_arg="$1"
      else
        _repo_dir="$1"
      fi
      shift
      ;;
  esac
done

if [ -z "$_repo_dir" ]; then
  if git rev-parse --show-toplevel >/dev/null 2>&1; then
    _repo_dir="$(git rev-parse --show-toplevel)"
  else
    _repo_dir="."
  fi
fi

if [ -z "$_gitmodules_arg" ] && [ -r "$_repo_dir/.gitmodules" ]; then
  _gitmodules_arg="$_repo_dir/.gitmodules"
fi

_entries="$(mktemp /tmp/gitea-submodule-rewrite-XXXXXX)"
trap 'rm -f "$_entries"' EXIT INT HUP TERM
load_entries "$_gitmodules_arg" > "$_entries" || die "no submodule list"

if [ ! -s "$_entries" ]; then
  die "no submodule entries parsed"
fi

log "Gitea base: $GITEA_ROOT_URL  owner=$GITEA_OWNER  repo=$_repo_dir"
printf '\n'

while IFS= read -r line; do
  [ -n "$line" ] || continue
  _repo="${line%%|*}"
  _rest="${line#*|}"
  _upstream="${_rest%%|*}"
  _path="${_rest#*|}"
  _gitea_url="$(gitea_public_repo_url_for "$GITEA_OWNER" "$_repo")"

  if [ "$_global" -eq 1 ]; then
    _cmd="git config --global url.$_gitea_url.insteadOf $_upstream"
    printf '%s\n' "$_cmd"
    if [ "$_apply" -eq 1 ]; then
      git config --global "url.$_gitea_url.insteadOf" "$_upstream"
    fi
  else
    _cmd="git -C \"$_repo_dir\" config submodule.$_path.url $_gitea_url"
    printf '%s\n' "$_cmd"
    if [ "$_apply" -eq 1 ]; then
      git -C "$_repo_dir" config "submodule.$_path.url" "$_gitea_url"
    fi
  fi
done < "$_entries"

if [ "$_apply" -eq 1 ] && [ "$_global" -eq 0 ]; then
  git -C "$_repo_dir" submodule sync --recursive
  log "applied; run: git -C $_repo_dir submodule update --init --recursive"
else
  printf '\n'
  log "To apply in this clone: $0 --apply"
  log "Or machine-wide URL rewrite: $0 --apply --global"
  log "Then: git submodule update --init --recursive"
fi
