#!/usr/bin/env bash
# Convert an SCP/tarball /opt/cnperp install into a git clone so Settings → Software Updates works.
# Run as root on the Hetzner server:
#   GITHUB_TOKEN=ghp_xxx bash /opt/cnperp/deploy/hetzner/enable-git-updates.sh
#
# Optional env:
#   APP_DIR=/opt/cnperp
#   APP_USER=cnperp
#   GIT_BRANCH=main
#   GIT_REPO=https://github.com/cassidymug/cnperpdimensions.git
set -euo pipefail

APP_DIR="${APP_DIR:-/opt/cnperp}"
APP_USER="${APP_USER:-cnperp}"
GIT_BRANCH="${GIT_BRANCH:-main}"
GIT_REPO="${GIT_REPO:-https://github.com/cassidymug/cnperpdimensions.git}"
ENV_FILE="${APP_DIR}/.env"

echo "==> CNPERP: enable git-based in-app updates"
echo "    App dir : $APP_DIR"
echo "    Branch  : $GIT_BRANCH"

if [[ ! -d "$APP_DIR" ]]; then
  echo "ERROR: $APP_DIR not found"
  exit 1
fi

# Load token from .env if not passed on command line
if [[ -z "${GITHUB_TOKEN:-}" ]] && [[ -f "$ENV_FILE" ]]; then
  GITHUB_TOKEN="$(grep -E '^GITHUB_TOKEN=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '\r' || true)"
  GITHUB_TOKEN="${GITHUB_TOKEN#\"}"
  GITHUB_TOKEN="${GITHUB_TOKEN%\"}"
  GITHUB_TOKEN="${GITHUB_TOKEN#\'}"
  GITHUB_TOKEN="${GITHUB_TOKEN%\'}"
fi

if [[ -n "${GITHUB_TOKEN:-}" ]]; then
  GIT_REPO="https://x-access-token:${GITHUB_TOKEN}@github.com/cassidymug/cnperpdimensions.git"
  echo "    Auth    : GitHub token (private repo)"
else
  echo "    Auth    : public clone (no GITHUB_TOKEN)"
fi

# Ensure git installed
if ! command -v git >/dev/null 2>&1; then
  apt-get update -qq
  apt-get install -y -qq git
fi

# Sudoers: cnperp can restart service for auto_update.sh
SUDOERS="/etc/sudoers.d/cnperp-update"
cat > "$SUDOERS" <<'SUDO'
# CNPERP in-app updates (auto_update.sh)
cnperp ALL=(root) NOPASSWD: /bin/systemctl restart cnperp
cnperp ALL=(root) NOPASSWD: /bin/systemctl is-active cnperp
SUDO
chmod 440 "$SUDOERS"
visudo -cf "$SUDOERS"

chown -R "$APP_USER:$APP_USER" "$APP_DIR"
mkdir -p "${APP_DIR}/logs"
chown "$APP_USER:$APP_USER" "${APP_DIR}/logs"

run_as_cnperp() {
  sudo -u "$APP_USER" bash -c "cd '$APP_DIR' && $*"
}

sync_from_origin() {
  echo "==> Syncing working tree to origin/$GIT_BRANCH"
  local backup_dir
  backup_dir="$(mktemp -d /tmp/cnperp-git-backup.XXXXXX)"
  echo "    Preserving local secrets/data in $backup_dir"
  for item in .env logs static/receipts static/uploads static/images data backups; do
    if [[ -e "${APP_DIR}/${item}" ]]; then
      cp -a "${APP_DIR}/${item}" "${backup_dir}/" 2>/dev/null || true
    fi
  done

  local clone_dir
  clone_dir="$(mktemp -d /tmp/cnperp-git-clone.XXXXXX)"
  git clone --branch "$GIT_BRANCH" --depth 1 "$GIT_REPO" "$clone_dir"

  # Replace app tree but keep venv (pip already installed)
  shopt -s dotglob
  for entry in "$APP_DIR"/*; do
    base="$(basename "$entry")"
    case "$base" in
      .env|logs|.venv|static) continue ;;
    esac
    rm -rf "$entry"
  done
  shopt -u dotglob

  cp -a "$clone_dir"/.git "$APP_DIR/"
  shopt -s dotglob
  for entry in "$clone_dir"/*; do
    base="$(basename "$entry")"
    [[ "$base" == ".git" ]] && continue
    cp -a "$entry" "$APP_DIR/"
  done
  shopt -u dotglob

  rm -rf "$clone_dir"

  for item in .env logs static/receipts static/uploads static/images data backups; do
    if [[ -e "${backup_dir}/${item}" ]]; then
      rm -rf "${APP_DIR}/${item}" 2>/dev/null || true
      cp -a "${backup_dir}/${item}" "${APP_DIR}/"
    fi
  done
  rm -rf "$backup_dir"

  chown -R "$APP_USER:$APP_USER" "$APP_DIR"
  run_as_cnperp "git config --global safe.directory '$APP_DIR'"
}

if [[ -d "${APP_DIR}/.git" ]]; then
  echo "==> Git already initialized — syncing from origin"
  run_as_cnperp "git remote set-url origin '$GIT_REPO'" || true
  if ! run_as_cnperp "git fetch origin '$GIT_BRANCH' --depth=1" 2>/dev/null; then
    run_as_cnperp "git remote set-url origin '$GIT_REPO'"
    run_as_cnperp "git fetch origin '$GIT_BRANCH' --depth=1"
  fi
  if ! run_as_cnperp "git checkout -B '$GIT_BRANCH' 'origin/$GIT_BRANCH'" 2>/dev/null; then
    echo "==> Checkout conflict — fresh sync (keeps .env, logs, .venv)"
    sync_from_origin
  else
    run_as_cnperp "git reset --hard 'origin/$GIT_BRANCH'"
  fi
else
  echo "==> Initializing git in existing install (preserves .env, logs, .venv)"
  sync_from_origin
fi

# Executable update scripts
chmod +x "${APP_DIR}/deploy/auto_update.sh" 2>/dev/null || true
chmod +x "${APP_DIR}/deploy/hetzner/run-migrations.sh" 2>/dev/null || true
chmod +x "${APP_DIR}/deploy/hetzner/deploy.sh" 2>/dev/null || true
chown -R "$APP_USER:$APP_USER" "${APP_DIR}/deploy"

# Persist update settings in .env
touch "$ENV_FILE"
grep -q '^UPDATE_ENABLED=' "$ENV_FILE" && sed -i 's/^UPDATE_ENABLED=.*/UPDATE_ENABLED=true/' "$ENV_FILE" || echo 'UPDATE_ENABLED=true' >> "$ENV_FILE"
grep -q '^UPDATE_BRANCH=' "$ENV_FILE" && sed -i "s/^UPDATE_BRANCH=.*/UPDATE_BRANCH=${GIT_BRANCH}/" "$ENV_FILE" || echo "UPDATE_BRANCH=${GIT_BRANCH}" >> "$ENV_FILE"
grep -q '^GITHUB_REPO=' "$ENV_FILE" && sed -i 's/^GITHUB_REPO=.*/GITHUB_REPO=cassidymug\/cnperpdimensions/' "$ENV_FILE" || echo 'GITHUB_REPO=cassidymug/cnperpdimensions' >> "$ENV_FILE"
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
  if grep -q '^GITHUB_TOKEN=' "$ENV_FILE"; then
    sed -i "s|^GITHUB_TOKEN=.*|GITHUB_TOKEN=${GITHUB_TOKEN}|" "$ENV_FILE"
  else
    echo "GITHUB_TOKEN=${GITHUB_TOKEN}" >> "$ENV_FILE"
  fi
fi
chown "$APP_USER:$APP_USER" "$ENV_FILE"
chmod 600 "$ENV_FILE"

# Store git credentials for future pulls (without token in remote URL long-term)
if [[ -n "${GITHUB_TOKEN:-}" ]]; then
  CRED_FILE="/home/${APP_USER}/.git-credentials"
  echo "https://x-access-token:${GITHUB_TOKEN}@github.com" > "$CRED_FILE"
  chown "$APP_USER:$APP_USER" "$CRED_FILE"
  chmod 600 "$CRED_FILE"
  run_as_cnperp "git config --global credential.helper store"
  run_as_cnperp "git config --global safe.directory '$APP_DIR'"
  # Use clean remote URL; credentials come from helper
  run_as_cnperp "git remote set-url origin 'https://github.com/cassidymug/cnperpdimensions.git'"
fi

run_as_cnperp "git config --global safe.directory '$APP_DIR'"

echo "==> Verifying git as $APP_USER"
run_as_cnperp "git rev-parse --short HEAD"
run_as_cnperp "git log -1 --oneline"
run_as_cnperp "git fetch origin '$GIT_BRANCH' --quiet && echo fetch_ok"

echo "==> Verifying sudo restart (NOPASSWD)"
sudo -u "$APP_USER" sudo systemctl is-active cnperp

systemctl restart cnperp
sleep 2
systemctl is-active cnperp && curl -sf http://127.0.0.1:8000/health | head -c 120 && echo ""

echo ""
echo "=============================================="
echo " Git updates ENABLED"
echo " Settings → Software Updates will now:"
echo "   • detect commits on origin/$GIT_BRANCH"
echo "   • run deploy/auto_update.sh (pull, pip, migrate, restart)"
echo " Commit: $(run_as_cnperp 'git rev-parse --short HEAD' 2>/dev/null || echo '?')"
echo "=============================================="
