#!/bin/sh
# Nexus Docker entrypoint — wait for deps, sync .env with persistent volume, exec uvicorn.
set -eu

PERSIST_DIR="${NEXUS_PERSIST_DIR:-/var/lib/nexus}"
PERSIST_ENV="${PERSIST_DIR}/.env"

wait_tcp() {
  host="$1"
  port="$2"
  echo "entrypoint: waiting for ${host}:${port}..."
  until python3 -c "
import socket
s = socket.socket()
s.settimeout(2)
s.connect(('${host}', ${port}))
s.close()
" 2>/dev/null; do
    sleep 2
  done
}

wait_tcp_optional() {
  host="$1"
  port="$2"
  tries="${3:-15}"
  label="${4:-service}"
  echo "entrypoint: waiting for ${label} ${host}:${port} (max ${tries} tries)..."
  n=0
  while [ "$n" -lt "$tries" ]; do
    if python3 -c "
import socket
s = socket.socket()
s.settimeout(2)
s.connect(('${host}', ${port}))
s.close()
" 2>/dev/null; then
      echo "entrypoint: ${label} ready at ${host}:${port}"
      return 0
    fi
    n=$((n + 1))
    sleep 2
  done
  echo "entrypoint: warn — ${label} not reachable at ${host}:${port}; install on host or set URL in .env"
  return 0
}

restore_persisted_install_lock() {
  if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" = "1" ]; then
    return 0
  fi
  PERSIST_LOCK="${PERSIST_DIR}/.install_locked"
  if [ -f "${PERSIST_LOCK}" ] && [ ! -f /app/.install_locked ]; then
    cp "${PERSIST_LOCK}" /app/.install_locked
    chmod 600 /app/.install_locked
    echo "entrypoint: restored .install_locked from ${PERSIST_LOCK}"
  fi
}

archive_install_wizard_if_locked() {
  if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" = "1" ]; then
    rm -f /app/.install_locked "${PERSIST_DIR}/.install_locked" 2>/dev/null || true
    if [ -f /app/web/app/install.html.bak ] && [ ! -f /app/web/app/install.html ]; then
      mv /app/web/app/install.html.bak /app/web/app/install.html
      echo "entrypoint: restored install.html from .bak (wizard pending)"
    fi
    return 0
  fi
  if [ ! -f /app/.install_locked ] && [ ! -f "${PERSIST_DIR}/.install_locked" ]; then
    return 0
  fi
  if [ -f /app/web/app/install.html.bak ]; then
    if [ -f /app/web/app/install.html ]; then
      rm -f /app/web/app/install.html
      echo "entrypoint: removed install.html (wizard archived as install.html.bak)"
    fi
    return 0
  fi
  if [ -f /app/web/app/install.html ]; then
    mv /app/web/app/install.html /app/web/app/install.html.bak
    echo "entrypoint: archived install.html → install.html.bak"
  fi
}

restore_persisted_env() {
  if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" = "1" ]; then
    return 0
  fi
  if [ ! -f "${PERSIST_ENV}" ]; then
    return 0
  fi
  if ! grep -q '^NEXUS_DATABASE_URL=' "${PERSIST_ENV}" 2>/dev/null; then
    echo "entrypoint: warn — ${PERSIST_ENV} missing NEXUS_DATABASE_URL; skip restore (complete install wizard)"
    return 0
  fi
  cp "${PERSIST_ENV}" /app/.env
  chmod 600 /app/.env
  echo "entrypoint: restored .env from ${PERSIST_ENV}"
}

# Compose may inject placeholder NEXUS_REDIS_URL (no password). Wizard .env wins.
export_app_env() {
  if [ ! -f /app/.env ]; then
    return 0
  fi
  set -a
  # shellcheck disable=SC1091
  . /app/.env
  set +a
  echo "entrypoint: exported NEXUS_* from /app/.env (overrides Compose placeholders)"
}

write_env_from_environment() {
  if [ -f /app/.env ]; then
    return 0
  fi
  if [ "${NEXUS_DOCKER_WRITE_ENV:-}" != "1" ]; then
    return 0
  fi
  if [ -z "${NEXUS_SECRET_KEY:-}" ]; then
    return 0
  fi
  if [ "${NEXUS_INSTALL_WIZARD_PENDING:-}" = "1" ]; then
    echo "entrypoint: install wizard pending — skip writing /app/.env"
    return 0
  fi
  if [ -z "${NEXUS_DATABASE_URL:-}" ]; then
    echo "entrypoint: skip writing /app/.env — NEXUS_DATABASE_URL not set (use /app/install.html)"
    return 0
  fi
  mkdir -p "${PERSIST_DIR}"
  {
    echo "# Generated by docker/entrypoint.sh — do not commit"
    env | grep '^NEXUS_' | sort
  } > /app/.env
  chmod 600 /app/.env
  cp /app/.env "${PERSIST_ENV}"
  echo "entrypoint: wrote .env from container environment"
}

persist_state_on_exit() {
  if [ -f /app/.env ]; then
    mkdir -p "${PERSIST_DIR}"
    cp /app/.env "${PERSIST_ENV}"
    chmod 600 "${PERSIST_ENV}" 2>/dev/null || true
  fi
  if [ -f /app/.install_locked ]; then
    mkdir -p "${PERSIST_DIR}"
    cp /app/.install_locked "${PERSIST_DIR}/.install_locked"
    chmod 600 "${PERSIST_DIR}/.install_locked" 2>/dev/null || true
  fi
}

trap persist_state_on_exit EXIT INT TERM

# MySQL / Redis 均由用户自行安装在宿主机；安装向导阶段不阻塞启动
if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" != "1" ] && [ "${NEXUS_SKIP_MYSQL_WAIT:-0}" != "1" ]; then
  MYSQL_HOST="${NEXUS_1PANEL_DB_HOST:-${MYSQL_HOST:-host.docker.internal}}"
  MYSQL_PORT="${MYSQL_PORT:-3306}"
  wait_tcp_optional "${MYSQL_HOST}" "${MYSQL_PORT}" 30 "MySQL"
fi

if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" != "1" ] && [ "${NEXUS_SKIP_REDIS_WAIT:-0}" != "1" ]; then
  REDIS_HOST="${NEXUS_1PANEL_REDIS_HOST:-${REDIS_HOST:-host.docker.internal}}"
  REDIS_PORT="${REDIS_PORT:-6379}"
  wait_tcp_optional "${REDIS_HOST}" "${REDIS_PORT}" 15 "Redis"
fi

restore_persisted_install_lock
archive_install_wizard_if_locked
restore_persisted_env
write_env_from_environment
export_app_env

exec "$@"
