#!/bin/ash
#
# Safe idempotent Gitea polish: org access (foxx), repo inventory, mirror sync,
# submodule mirrors, default branch next. Does NOT delete repos unless
# GITEA_RECREATE_MAIN_MIRROR=yes (android_cast pull-mirror repair).
#
# Usage (BE as root):
#   sudo ./gitea_polish_project.sh
#   sudo ./gitea_polish_project.sh /var/www/.../androidcast_project/android_cast
#
set -eu

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=gitea_ini.sh
. "$SCRIPT_DIR/gitea_ini.sh"
# shellcheck source=gitea_mirror_lib.sh
. "$SCRIPT_DIR/gitea_mirror_lib.sh"
# shellcheck source=gitea_org_lib.sh
. "$SCRIPT_DIR/gitea_org_lib.sh"
# shellcheck source=gitea_submodule_lib.sh
. "$SCRIPT_DIR/gitea_submodule_lib.sh"

GITEA_ORG="${GITEA_ORG:-AndroidCast}"
GITEA_OWNER="${GITEA_OWNER:-$GITEA_ORG}"
GITEA_REPO="${GITEA_REPO:-android_cast}"
GITEA_MIRROR_URL="${GITEA_MIRROR_URL:-git://10.7.0.10/android_cast}"
GITEA_DEFAULT_BRANCH="${GITEA_DEFAULT_BRANCH:-next}"
GITEA_SUBMODULES_CONF="${GITEA_SUBMODULES_CONF:-$SCRIPT_DIR/submodules.defaults.conf}"
GITEA_RECREATE_MAIN_MIRROR="${GITEA_RECREATE_MAIN_MIRROR:-}"

log() { printf '[gitea-polish] %s\n' "$*"; }
warn() { printf '[gitea-polish] WARN: %s\n' "$*" >&2; }

json_bool() {
  printf '%s' "$1" | tr -d '\n' | grep -o "\"$2\":[^,}]*" | head -1 | sed 's/.*://;s/ //g'
}

repo_mirror_status() {
  _owner="$1"
  _repo="$2"
  gitea_repo_exists_api "$_owner" "$_repo" || return 1
  _meta="$(gitea_repo_get_api "$_owner" "$_repo")"
  _mirror="$(json_bool "$_meta" "mirror")"
  _updated="$(printf '%s' "$_meta" | tr -d '\n' | grep -o '"updated_at":"[^"]*"' | head -1 | sed 's/.*:"//;s/"$//')"
  log "  $_owner/$_repo  mirror=$_mirror  updated=$_updated"
  [ "$_mirror" = "true" ]
}

list_owner_repos() {
  _owner="$1"
  log "repos under $_owner:"
  _names="$(gitea_list_repos_api "$_owner" 2>/dev/null)" || _names=""
  if [ -z "$(echo "$_names" | tr -d ' ')" ]; then
    warn "  (none)"
    return 1
  fi
  echo "$_names" | while read -r _r; do
    [ -n "$_r" ] && log "  - $_owner/$_r"
  done
  return 0
}

gitea_org_team_members() {
  _org="$1"
  _team_id="$(gitea_org_owners_team_id "$_org")" || return 1
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  curl -sS "$_api/teams/$_team_id/members" \
    -H "Authorization: token $_token" \
    | awk -F'"' '/"login":/ { print $4 }'
}

verify_org_access() {
  log "org $GITEA_ORG Owners team members:"
  gitea_org_team_members "$GITEA_ORG" | while read -r _u; do
    [ -n "$_u" ] && log "  - $_u"
  done
  for _u in $GITEA_ORG_OWNERS; do
    if gitea_org_team_members "$GITEA_ORG" | grep -Fx "$_u" >/dev/null 2>&1; then
      log "ok: $_u is org Owner"
    else
      warn "missing: $_u NOT in Owners — re-run gitea_migrate_org_setup.sh"
    fi
  done
}

sync_all_mirrors() {
  log "trigger mirror sync (all repos)..."
  if gitea_cli "admin" "repo-sync-mirrors"; then
    log "repo-sync-mirrors OK"
    return 0
  fi
  warn "repo-sync-mirrors CLI failed — trying per-repo API"
  for _owner in "$GITEA_ORG" admin; do
    gitea_list_repos_api "$_owner" 2>/dev/null | while read -r _r; do
      [ -n "$_r" ] || continue
      gitea_sync_mirror_api "$_owner" "$_r" && log "  synced $_owner/$_r" \
        || warn "  sync failed $_owner/$_r"
    done
  done
}

ensure_url_shortener_mirror() {
  gitea_repo_exists_api "$GITEA_ORG" url-shortener && {
    log "url-shortener mirror present under $GITEA_ORG"
    return 0
  }
  log "url-shortener missing — running gitea_attach_url_shortener.sh ..."
  sh "$SCRIPT_DIR/gitea_attach_url_shortener.sh" \
    || warn "url-shortener attach failed — run: sudo ./gitea_attach_url_shortener.sh"
}

mirror_submodules_if_missing() {
  _checkout="${1:-}"
  _repo_dir=""
  _gitmodules=""
  if [ -n "$_checkout" ] && [ -d "$_checkout" ]; then
    _repo_dir="$(cd "$_checkout" && pwd)"
    _gitmodules="$_repo_dir/.gitmodules"
  fi

  _need=0
  for _sub in libvpx opus speex wireguard-android; do
    gitea_repo_exists_api "$GITEA_ORG" "$_sub" && continue
    _need=1
    break
  done
  [ "$_need" -eq 1 ] || {
    log "submodule mirrors present under $GITEA_ORG"
    return 0
  }

  log "creating missing submodule mirrors under $GITEA_ORG..."
  _list="$(mktemp /tmp/gitea-polish-sub-XXXXXX)"
  gitea_submodule_collect_entries "$_repo_dir" HEAD "$_gitmodules" "$GITEA_SUBMODULES_CONF" > "$_list"
  while IFS= read -r _line; do
    [ -n "$_line" ] || continue
    _name="${_line%%|*}"
    _rest="${_line#*|}"
    _url="${_rest%%|*}"
    log "  mirror $_name <- $_url"
    gitea_mirror_pull_repo "$_url" "$_name" "$GITEA_ORG" "24h" "/tmp/gitea-polish-$$" \
      && gitea_sync_mirror_api "$GITEA_ORG" "$_name" || warn "  failed $_name"
    gitea_rm_path "/tmp/gitea-polish-$$/${_name}.mirror.git"
  done < "$_list"
  gitea_rm_path "$_list"
}

recreate_main_pull_mirror_if_asked() {
  if [ "$GITEA_RECREATE_MAIN_MIRROR" != "yes" ]; then
    return 0
  fi
  warn "GITEA_RECREATE_MAIN_MIRROR=yes — delete $GITEA_ORG/$GITEA_REPO and re-attach"
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  curl -sS -o /dev/null -X DELETE "$_api/repos/$GITEA_ORG/$GITEA_REPO" \
    -H "Authorization: token $_token" || true
  GITEA_OWNER="$GITEA_ORG" "$SCRIPT_DIR/gitea_attach_remote.sh" "$GITEA_MIRROR_URL"
}

# --- main ---

_checkout="${1:-}"
if [ -d "./.git" ] || [ -f "./.git" ]; then
  _checkout="${_checkout:-$(pwd)}"
fi

gitea_load_config || exit 1
gitea_ensure_cli_access || exit 1

log "=== Gitea polish (safe) ==="
log "ini=$GITEA_APP_INI  org=$GITEA_ORG"

# 1) Org + foxx Owners
gitea_org_ensure_androidcast "$GITEA_ORG" || warn "org setup incomplete"
verify_org_access

# 2) Inventory
list_owner_repos "$GITEA_ORG" || true
list_owner_repos admin || true

# 3) Main mirror health
log "main repo mirror status:"
_main_ok=0
if repo_mirror_status "$GITEA_ORG" "$GITEA_REPO"; then
  _main_ok=1
elif repo_mirror_status "admin" "$GITEA_REPO"; then
  warn "android_cast still under admin — transfer to org:"
  warn "  sudo ./gitea_migrate_org_setup.sh"
  _main_ok=1
else
  warn "no pull mirror for $GITEA_REPO — auto-sync disabled"
  warn "fix (destructive): GITEA_RECREATE_MAIN_MIRROR=yes sudo ./gitea_polish_project.sh"
  warn "  or delete $GITEA_ORG/$GITEA_REPO in UI then: sudo ./gitea_attach_remote.sh $GITEA_MIRROR_URL"
fi

recreate_main_pull_mirror_if_asked

# 4) Manual sync now
sync_all_mirrors

# 5) Submodules
mirror_submodules_if_missing "$_checkout"

# 5b) First-party submodule url-shortener (local git:// — not gitea_mirror_submodules)
ensure_url_shortener_mirror

# 6) Default branch
if command -v "$SCRIPT_DIR/gitea_set_default_branch.sh" >/dev/null 2>&1; then
  GITEA_OWNER="$GITEA_ORG" GITEA_DEFAULT_BRANCH="$GITEA_DEFAULT_BRANCH" \
    sh "$SCRIPT_DIR/gitea_set_default_branch.sh" || warn "default branch set failed (sync first)"
fi

# 7) Branch protection (master, next)
if [ "${GITEA_SKIP_BRANCH_PROTECT:-0}" -eq 0 ]; then
  sh "$SCRIPT_DIR/gitea_protect_branches.sh" || warn "branch protection failed — run manually"
fi

# 8) Summary
log "=== done ==="
cat <<EOF

UI checklist:
  • foxx/admin: open ${GITEA_ROOT_URL%/}/$GITEA_ORG  (org page — not only "Your repositories")
  • Expect: android_cast, url-shortener, libvpx, opus, speex under $GITEA_ORG
  • If android_cast still stale: sudo ./gitea_diagnose_mirror_sync.sh
  • Branch protection: master/next on Gitea; install FE hook:
      examples/git/hooks/pre-receive.android_cast.example
  • Email/2FA later: app.ini REGISTER_EMAIL_CONFIRM=false; add SMTP when ready

EOF

[ "$_main_ok" -eq 1 ] || exit 2
