#!/bin/ash
# Gitea organization, team, and user helpers (AndroidCast team layout).
# shellcheck shell=sh
# Requires: . gitea_ini.sh && gitea_load_config && . gitea_mirror_lib.sh

GITEA_ORG="${GITEA_ORG:-AndroidCast}"
GITEA_ORG_FULL_NAME="${GITEA_ORG_FULL_NAME:-Android Cast}"
GITEA_ORG_VISIBILITY="${GITEA_ORG_VISIBILITY:-public}"
# Space-separated Gitea logins with org Owner (admin) team membership.
GITEA_ORG_OWNERS="${GITEA_ORG_OWNERS:-admin foxx}"
# Transfer mirrors from a personal account when re-homing under the org.
GITEA_TRANSFER_FROM="${GITEA_TRANSFER_FROM:-admin}"

gitea_org_log() { printf '[gitea-org] %s\n' "$*"; }
gitea_org_warn() { printf '[gitea-org] WARN: %s\n' "$*" >&2; }

gitea_api_token() {
  _token="${GITEA_ADMIN_TOKEN:-}"
  [ -n "$_token" ] || _token="$(gitea_resolve_push_token)" || return 1
  printf '%s' "$_token"
}

gitea_org_exists() {
  _org="$1"
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  _http="$(curl -sS -o /dev/null -w '%{http_code}' \
    "$_api/orgs/$_org" \
    -H "Authorization: token $_token")"
  [ "$_http" = "200" ]
}

gitea_owner_exists() {
  _name="$1"
  gitea_org_exists "$_name" && return 0
  gitea_user_exists "$_name"
}

gitea_org_create_api() {
  _org="$1"
  _full="${2:-$GITEA_ORG_FULL_NAME}"
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  _payload=$(cat <<EOF
{
  "username": "$_org",
  "full_name": "$_full",
  "description": "Android Cast project mirrors and sources",
  "visibility": "$GITEA_ORG_VISIBILITY",
  "repo_admin_change_team_access": true
}
EOF
)
  _resp="$(mktemp /tmp/gitea-org-create-XXXXXX.json)"
  _http="$(curl -sS -o "$_resp" -w '%{http_code}' \
    -X POST "$_api/orgs" \
    -H "Authorization: token $_token" \
    -H "Content-Type: application/json" \
    -d "$_payload")"
  _rc=1
  case "$_http" in
    201|200) _rc=0 ;;
    409|422)
      gitea_org_exists "$_org" && _rc=0
      ;;
  esac
  gitea_rm_path "$_resp"
  return "$_rc"
}

gitea_user_create_if_missing() {
  _user="$1"
  _email="${2:-${_user}@local}"
  if gitea_user_exists "$_user"; then
    gitea_org_log "user exists: $_user"
    return 0
  fi
  gitea_org_log "creating user $_user (password/SSH key: set later in Gitea UI)"
  _pw="setme-$(date +%s)-$$"
  if gitea_cli "admin" "user" "create" \
    "--username" "$_user" \
    "--email" "$_email" \
    "--password" "$_pw" \
    "--must-change-password" 2>/dev/null; then
    return 0
  fi
  if gitea_cli "admin" "user" "create" \
    "--username" "$_user" \
    "--email" "$_email" \
    "--random-password" \
    "--must-change-password" 2>/dev/null; then
    return 0
  fi
  gitea_org_warn "could not create user $_user via CLI — create in Gitea UI"
  return 1
}

gitea_org_owners_team_id() {
  _org="$1"
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  _json="$(curl -sS "$_api/orgs/$_org/teams" -H "Authorization: token $_token")"
  _id="$(printf '%s' "$_json" | awk '
    /"name":"Owners"/ || /"name": "Owners"/ {
      for (i = 1; i <= NF; i++) if ($i ~ /^"id":/) { gsub(/[^0-9]/, "", $(i+1)); print $(i+1); exit }
    }
  ')"
  if [ -z "$_id" ]; then
    _id="$(printf '%s' "$_json" | tr ',' '\n' | awk '
      /"name":"Owners"/ { found=1 }
      found && /"id":/ { gsub(/[^0-9]/, "", $0); print; exit }
    ')"
  fi
  [ -n "$_id" ] || return 1
  printf '%s' "$_id"
}

gitea_org_team_has_member() {
  _org="$1"
  _user="$2"
  _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" \
    | grep -q "\"login\":\"$_user\""
}

gitea_team_add_member_api() {
  _team_id="$1"
  _user="$2"
  command -v curl >/dev/null 2>&1 || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  _http="$(curl -sS -o /dev/null -w '%{http_code}' \
    -X PUT "$_api/teams/$_team_id/members/$_user" \
    -H "Authorization: token $_token")"
  case "$_http" in
    204|200|201) return 0 ;;
    422) return 0 ;;
    *) return 1 ;;
  esac
}

gitea_org_add_owners() {
  _org="$1"
  _team_id="$(gitea_org_owners_team_id "$_org")" || {
    gitea_org_warn "Owners team not found for org $_org"
    return 1
  }
  for _u in $GITEA_ORG_OWNERS; do
    [ -n "$_u" ] || continue
    gitea_user_create_if_missing "$_u" || true
    if gitea_user_exists "$_u"; then
      if gitea_org_team_has_member "$_org" "$_u"; then
        gitea_org_log "Owners team: $_u (already member)"
      elif gitea_team_add_member_api "$_team_id" "$_u"; then
        gitea_org_log "Owners team: $_u (added)"
      else
        gitea_org_warn "could not add $_u to Owners — add in UI: Org $_org -> Teams -> Owners"
      fi
    fi
  done
  return 0
}

gitea_transfer_repo_api() {
  _from="$1"
  _repo="$2"
  _to="$3"
  command -v curl >/dev/null 2>&1 || return 1
  gitea_repo_exists_api "$_from" "$_repo" || return 1
  _token="$(gitea_api_token)" || return 1
  _api="$(gitea_api_base)"
  _payload="{\"new_owner\":\"$_to\",\"team_ids\":[]}"
  _resp="$(mktemp /tmp/gitea-transfer-XXXXXX.json)"
  _http="$(curl -sS -o "$_resp" -w '%{http_code}' \
    -X POST "$_api/repos/$_from/$_repo/transfer" \
    -H "Authorization: token $_token" \
    -H "Content-Type: application/json" \
    -d "$_payload")"
  _rc=1
  case "$_http" in
    200|201|202) _rc=0 ;;
    409|422)
      gitea_repo_exists_api "$_to" "$_repo" && _rc=0
      ;;
  esac
  gitea_rm_path "$_resp"
  return "$_rc"
}

# Move known project mirrors from GITEA_TRANSFER_FROM → org (no-op if absent).
gitea_org_transfer_legacy_repos() {
  _org="$1"
  _from="${2:-$GITEA_TRANSFER_FROM}"
  [ "$_from" = "$_org" ] && return 0
  for _repo in android_cast libvpx opus speex wireguard-android; do
    if gitea_repo_exists_api "$_from" "$_repo"; then
      gitea_org_log "transfer $_from/$_repo -> $_org/$_repo"
      gitea_transfer_repo_api "$_from" "$_repo" "$_org" \
        && gitea_org_log "  transferred" \
        || gitea_org_warn "  transfer failed"
    fi
  done
}

# Org + Owners team + foxx/admin. Idempotent.
gitea_org_ensure_androidcast() {
  _org="${1:-$GITEA_ORG}"

  if gitea_org_exists "$_org"; then
    gitea_org_log "org exists: $_org"
  else
    gitea_org_log "creating org $_org"
    gitea_org_create_api "$_org" || {
      gitea_org_warn "org create failed — create $_org in Gitea UI first"
      return 1
    }
  fi

  gitea_org_add_owners "$_org"
  gitea_org_transfer_legacy_repos "$_org" "$GITEA_TRANSFER_FROM"
  return 0
}
