#!/usr/bin/env bash
set -euo pipefail

# #region docker.backend.entrypoint [C:4] [TYPE Module] [SEMANTICS docker,entrypoint,enterprise,certs]
# @BRIEF Container entrypoint — установка корп. сертификатов, wait-for-DB,
#   Alembic миграции, bootstrap admin, затем запуск backend (exec "$@").
# @PRE Python runtime и backend source доступны в /app/backend.
#   Переменная CERTS_PATH указывает на директорию с .crt файлами (или пусто).
#   DATABASE_URL установлен и указывает на доступный PostgreSQL.
# @POST Сертификаты установлены в системное хранилище и NSS базу Chromium.
#   БД подтверждена как доступная. Alembic миграции применены.
#   Admin создан (если INITIAL_ADMIN_CREATE=true). Backend запущен через exec "$@".
# @SIDE_EFFECT Модифицирует /usr/local/share/ca-certificates/ и вызывает update-ca-certificates.
#   Импортирует CA в NSS DB (~/.pki/nssdb) для Chromium.
#   Выполняет Alembic upgrade head.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> [backend/src/scripts/create_admin.py]
# @RELATION DEPENDS_ON -> [backend/src/scripts/init_auth_db.py]
# @INVARIANT Если CERTS_PATH пуст или нет .crt файлов — install_certificates не падает.
# @INVARIANT Существующий admin аккаунт НЕ перезаписывается при перезапуске контейнера
#   (create_admin.py идемпотентен).
# @INVARIANT Повторный запуск install_llm_ca_certs не дублирует сертификаты в bundle.
# @INVARIANT Повторный запуск install_ca_to_nss не дублирует сертификаты в NSS DB.
# @INVARIANT wait_for_db exit(1) если БД недоступна после DB_WAIT_ATTEMPTS попыток —
#   контейнер не продолжит запуск с недоступной БД.
# @INVARIANT Alembic миграции выполняются ТОЛЬКО в entrypoint, НЕ в app.py lifespan.
# #endregion docker.backend.entrypoint

# ======================================================================
#  install_certificates — корпоративные CA-сертификаты
# ======================================================================
# #region docker.backend.entrypoint.install_certificates [C:3] [TYPE Function]
# @BRIEF Устанавливает корпоративные .crt сертификаты из CERTS_PATH в системное хранилище Debian.
# @PRE CERTS_PATH указывает на директорию (может быть пуста или не существовать).
#   В системе установлен пакет ca-certificates.
# @POST .crt файлы скопированы в /usr/local/share/ca-certificates/custom/ и
#   добавлены в системное хранилище через update-ca-certificates.
# @SIDE_EFFECT Запускает update-ca-certificates — модифицирует /etc/ssl/certs/.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> [ca-certificates (system package)]
# @EXAMPLE:
#   CERTS_PATH=/opt/certs docker run ...  # монтируем ./certs в /opt/certs
#   В ./certs кладём: my-corporate-ca.crt, another-ca.crt
#   entrypoint установит оба в доверенные.
install_certificates() {
  local certs_dir="${CERTS_PATH:-/opt/certs}"

  if [ ! -d "$certs_dir" ]; then
    echo "[entrypoint] CERTS_PATH=${certs_dir} не существует — пропускаем установку сертификатов"
    return 0
  fi

  local cert_count
  cert_count="$(find "$certs_dir" -maxdepth 1 \( -name '*.crt' -o -name '*.pem' \) 2>/dev/null | wc -l)"

  if [ "$cert_count" -eq 0 ]; then
    echo "[entrypoint] Нет .crt/.pem файлов в ${certs_dir} — пропускаем установку сертификатов"
    return 0
  fi

  local target="/usr/local/share/ca-certificates/custom"
  mkdir -p "$target"

  echo "[entrypoint] Устанавливаем корпоративные сертификаты из ${certs_dir}..."
  local copied=0
  # nullglob: если файлов нет, цикл не выполняется
  shopt -s nullglob
  for cert in "$certs_dir"/*.crt "$certs_dir"/*.pem; do
    cp -v "$cert" "$target/" 2>&1 | sed 's/^/[entrypoint]   /'
    copied=$((copied + 1))
  done
  shopt -u nullglob

  if [ "$copied" -eq 0 ]; then
    echo "[entrypoint] Нет файлов для копирования — пропускаем"
    return 0
  fi

  echo "[entrypoint] Обновляем системное хранилище CA-сертификатов..."
  update-ca-certificates --fresh 2>&1 | sed 's/^/[entrypoint]   /'

  echo "[entrypoint] ✅ Установлено ${copied} корпоративных сертификатов"
}
# #endregion docker.backend.entrypoint.install_certificates

# ======================================================================
#  install_llm_ca_certs — скачка и установка CA-сертификатов по URL
# ======================================================================
# #region docker.backend.entrypoint.install_llm_ca_certs [C:4] [TYPE Function]
# @BRIEF Скачивает PEM/DER-сертификаты из LLM_CA_CERT_URLS, конвертирует DER→PEM,
#   устанавливает в системное хранилище, создаёт хеш-симлинки и при необходимости
#   добавляет в ca-certificates.crt напрямую (fallback для OpenSSL 3-совместимости).
# @RATIONALE DER→PEM конвертация необходима, т.к. update-ca-certificates ожидает
#   PEM-формат (-----BEGIN CERTIFICATE-----). Корпоративные PKI часто отдают
#   сертификаты в DER (бинарном) формате через HTTP.
# @RATIONALE Хеш-симлинки создаются с поддержкой коллизий (.0, .1, .2...), т.к.
#   update-ca-certificates в Debian Bookworm иногда пропускает создание ссылок
#   для сертификатов из поддиректорий. Fingerprint (SHA256) используется для
#   детекции дубликатов вместо имени файла — защита от ложных срабатываний grep.
# @RATIONALE Fallback cat в ca-certificates.crt гарантирует что OpenSSL 3.x
#   увидит сертификаты даже если update-ca-certificates их пропустит.
#   Перед добавлением проверяется fingerprint — при повторном запуске
#   сертификат не дублируется.
# @REJECTED Вариант "только контейнерный volume с .crt файлами" отвергнут —
#   требует ручного копирования сертификатов на хост перед запуском.
#   URL-based подход позволяет централизованно управлять сертификатами через PKI.
# @REJECTED Использование grep по имени файла/серийному номеру для детекции
#   дубликатов отвергнуто — имя файла может совпадать с содержимым PEM,
#   а серийный номер не уникален при ротации CA. Fingerprint (SHA256)
#   является криптографически уникальным идентификатором.
# @PRE LLM_CA_CERT_URLS — строка с URL через пробел; curl и openssl установлены.
# @POST Сертификаты доступны в /etc/ssl/certs/ca-certificates.crt.
#   Хеш-симлинки созданы для каждого сертификата (с поддержкой коллизий).
# @SIDE_EFFECT Скачивает файлы из внешних URL. Модифицирует /etc/ssl/certs/.
# @LAYER Infrastructure
# @EXAMPLE:
#   LLM_CA_CERT_URLS="http://pki.company.com/root.crt http://pki.company.com/intermediate.crt"
install_llm_ca_certs() {
  local urls="${LLM_CA_CERT_URLS:-}"
  if [ -z "$urls" ]; then
    echo "[entrypoint] LLM_CA_CERT_URLS не задан — пропускаем скачку сертификатов"
    return 0
  fi

  local work_dir="/tmp/llm-ca-certs"
  local target_dir="/usr/local/share/ca-certificates/llm"
  mkdir -p "$work_dir" "$target_dir"

  echo "[entrypoint] === Скачивание и установка LLM CA-сертификатов ==="
  local index=0

  for url in $urls; do
    url="$(echo "$url" | xargs)"  # trim
    [ -z "$url" ] && continue
    index=$((index + 1))

    # Определяем имя файла из URL, или генерируем
    local filename
    filename="$(basename "$url" | sed 's/[?#].*//')"
    if [ -z "$filename" ] || [ "$filename" = "." ] || [ "$filename" = ".." ]; then
      filename="llm-ca-${index}.crt"
    fi

    local raw_file="${work_dir}/${filename}"
    local pem_file="${target_dir}/$(echo "$filename" | sed 's/\.[^.]*$//').crt"

    echo "[entrypoint]   [${index}] Скачивание: ${url}"

    # Скачиваем с retry 3 раза
    local attempt=0
    local success=0
    while [ $attempt -lt 3 ]; do
      attempt=$((attempt + 1))
      # Сначала пробуем с verify, если не получилось — с --insecure
      # (chicken-and-egg: PKI сервер может использовать тот же CA, который мы скачиваем)
      if curl -sS --connect-timeout 10 --max-time 30 -o "$raw_file" "$url" 2>/dev/null; then
        success=1
        break
      fi
      # TLS verify failed? Пробуем без проверки (корп. PKI bootstrap)
      if [ $attempt -eq 1 ]; then
        echo "[entrypoint]     ↻ TLS verify failed, retrying with --insecure..."
        if curl -sS -k --connect-timeout 10 --max-time 30 -o "$raw_file" "$url" 2>/dev/null; then
          echo "[entrypoint]     ✓ Скачано с --insecure (проверка fingerprint в конце)"
          success=1
          break
        fi
      fi
      echo "[entrypoint]   ⚠ Попытка ${attempt}/3 не удалась, повтор через 2с..."
      sleep 2
    done

    if [ "$success" -eq 0 ]; then
      echo "[entrypoint]   ❌ Не удалось скачать: ${url} — пропускаем"
      continue
    fi

    # Определяем формат: PEM или DER
    if openssl x509 -in "$raw_file" -inform PEM -noout 2>/dev/null; then
      echo "[entrypoint]   ✓ Формат: PEM"
      cp "$raw_file" "$pem_file"
    elif openssl x509 -in "$raw_file" -inform DER -noout 2>/dev/null; then
      echo "[entrypoint]   ↻ Формат: DER — конвертируем в PEM"
      if ! openssl x509 -in "$raw_file" -inform DER -out "$pem_file" -outform PEM 2>&1; then
        echo "[entrypoint]   ❌ Ошибка конвертации DER→PEM — пропускаем"
        rm -f "$raw_file" "${pem_file}"
        continue
      fi
    else
      echo "[entrypoint]   ❌ Неизвестный формат (не PEM и не DER) — пропускаем"
      # Выводим первые 20 байт для диагностики
      local first_bytes
      first_bytes="$(head -c 20 "$raw_file" 2>/dev/null | cat -v)"
      echo "[entrypoint]     Первые 20 байт: ${first_bytes}"
      rm -f "$raw_file"
      continue
    fi

    chmod 644 "$pem_file"
    echo "[entrypoint]   ✅ Установлен: $(basename "$pem_file")"
    rm -f "$raw_file"
  done

  if [ -z "$(ls -A "$target_dir" 2>/dev/null)" ]; then
    echo "[entrypoint] Нет скачанных сертификатов — пропускаем"
    rm -rf "$work_dir"
    return 0
  fi

  # Обновляем системное хранилище
  echo "[entrypoint] --- Обновление системного хранилища CA-сертификатов ---"
  update-ca-certificates --fresh 2>&1 | sed 's/^/[entrypoint]   /'

  # Проверяем, попали ли сертификаты в бандл, и создаём хеш-симлинки
  echo "[entrypoint] --- Валидация установки сертификатов ---"

  for cert_file in "$target_dir"/*.crt; do
    [ -f "$cert_file" ] || continue
    local cert_name
    cert_name="$(basename "$cert_file" .crt)"
    local cert_subject
    cert_subject="$(openssl x509 -in "$cert_file" -noout -subject 2>/dev/null | head -1 || echo "unknown")"
    local cert_fingerprint
    cert_fingerprint="$(openssl x509 -in "$cert_file" -noout -fingerprint -sha256 2>/dev/null | sed 's/.*=//' || echo "")"

    # Проверяем есть ли в ca-certificates.crt по fingerprint (криптографически уникален)
    if [ -n "$cert_fingerprint" ] && \
       grep -qF "$cert_fingerprint" /etc/ssl/certs/ca-certificates.crt 2>/dev/null; then
      echo "[entrypoint]   ✅ ${cert_name} — в ca-certificates.crt (${cert_subject})"
    else
      echo "[entrypoint]   ⚠ ${cert_name} — НЕ в ca-certificates.crt. Добавляем напрямую..."
      cat "$cert_file" >> /etc/ssl/certs/ca-certificates.crt
      echo "[entrypoint]   ➕ Добавлен напрямую в ca-certificates.crt"
    fi

    # Создаём хеш-симлинку с поддержкой коллизий (.0, .1, .2...)
    local hash_val
    hash_val="$(openssl x509 -in "$cert_file" -noout -hash 2>/dev/null || true)"
    if [ -n "$hash_val" ]; then
      local suffix=0
      local link_path="/etc/ssl/certs/${hash_val}.${suffix}"
      # Ищем первый свободный suffix или symlink уже указывающий на наш файл
      while [ -L "$link_path" ]; do
        if [ "$(readlink "$link_path")" = "$cert_file" ]; then
          break 2  # уже есть, ничего не делаем
        fi
        suffix=$((suffix + 1))
        link_path="/etc/ssl/certs/${hash_val}.${suffix}"
      done
      if [ ! -L "$link_path" ]; then
        ln -sf "$cert_file" "$link_path"
        echo "[entrypoint]   🔗 Создана симлинка: ${hash_val}.${suffix} → ${cert_name}"
      fi
    fi
  done

  # Проверяем итоговое количество
  local total_in_bundle
  total_in_bundle="$(awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' \
    < /etc/ssl/certs/ca-certificates.crt 2>/dev/null | wc -l || echo "0")"
  echo "[entrypoint] ✅ Всего сертификатов в bundle: ${total_in_bundle}"

  rm -rf "$work_dir"
  echo "[entrypoint] === Установка LLM CA-сертификатов завершена ==="
}
# #endregion docker.backend.entrypoint.install_llm_ca_certs

# ======================================================================
#  bootstrap_admin — создание admin пользователя
# ======================================================================
# #region docker.backend.entrypoint.bootstrap_admin [C:2] [TYPE Function]
# @BRIEF Создание admin пользователя из переменных окружения (идемпотентно).
# @PRE INITIAL_ADMIN_CREATE=true, INITIAL_ADMIN_USERNAME и INITIAL_ADMIN_PASSWORD заданы.
# @POST Admin пользователь создан в БД (если ещё не существовал).
# @LAYER Infrastructure
bootstrap_admin() {
  local create_flag="${INITIAL_ADMIN_CREATE:-false}"
  local username="${INITIAL_ADMIN_USERNAME:-}"
  local password="${INITIAL_ADMIN_PASSWORD:-}"
  local email="${INITIAL_ADMIN_EMAIL:-}"

  case "${create_flag,,}" in
    true|1|yes|y)
      ;;
    *)
      echo "[entrypoint] INITIAL_ADMIN_CREATE disabled — пропускаем bootstrap admin"
      return 0
      ;;
  esac

  if [[ -z "${username}" ]]; then
    echo "[entrypoint] INITIAL_ADMIN_USERNAME required when INITIAL_ADMIN_CREATE=true" >&2
    return 1
  fi

  if [[ -z "${password}" ]]; then
    echo "[entrypoint] INITIAL_ADMIN_PASSWORD required when INITIAL_ADMIN_CREATE=true" >&2
    return 1
  fi

  echo "[entrypoint] Initializing auth database..."
  python3 src/scripts/init_auth_db.py

  echo "[entrypoint] Creating admin user '${username}' (idempotent)..."
  if [[ -n "${email}" ]]; then
    python3 src/scripts/create_admin.py --username "${username}" --password "${password}" --email "${email}"
  else
    python3 src/scripts/create_admin.py --username "${username}" --password "${password}"
  fi

  echo "[entrypoint] ✅ Admin bootstrap complete"
}
# #endregion docker.backend.entrypoint.bootstrap_admin

# ======================================================================
#  install_ca_to_nss — импорт корпоративных CA в NSS базу Chromium
# ======================================================================
# #region docker.backend.entrypoint.install_ca_to_nss [C:3] [TYPE Function]
# @BRIEF Импортирует PEM-сертификаты из /usr/local/share/ca-certificates/
#   в NSS Shared DB (~/.pki/nssdb), чтобы Chromium (Playwright) доверял
#   корпоративным CA (исправляет ERR_CERT_AUTHORITY_INVALID).
# @RATIONALE Playwright's Chromium использует NSS Shared DB (~/.pki/nssdb)
#   для CA trust, отдельно от системного OpenSSL bundle. update-ca-certificates
#   добавляет сертификаты в /etc/ssl/certs/, но Chromium их не видит.
#   certutil -A -t "C,," импортирует PEM как доверенный CA для TLS.
# @RATIONALE NSS импорт выполняется после install_llm_ca_certs (скачивает .pem)
#   и update-ca-certificates (устанавливает в систему). Этот порядок
#   гарантирует, что PEM-файлы уже есть на диске до создания NSS DB.
# @RATIONALE Для дедупликации используется SHA256 fingerprint сертификата,
#   а не nickname — nickname может совпадать для файлов из разных директорий.
#   Nickname формируется как "llm-имя" или "custom-имя" для избежания коллизий.
# @REJECTED Использование Playwright --ignore-certificate-errors отвергнуто —
#   отключает ВСЕ SSL проверки глобально, а не только для корп. CA.
# @REJECTED Nickname-only дедупликация отвергнута — при разных файлах
#   с одинаковым именем из разных директорий второй молча пропускается.
# @PRE certutil (libnss3-tools) установлен. PEM-файлы есть в target_dirs.
# @POST Сертификаты добавлены в NSS базу Chromium с trust-атрибутами "C,,".
#   Повторный вызов не дублирует сертификаты.
# @SIDE_EFFECT Создаёт ~/.pki/nssdb/ если не существовал.
# @LAYER Infrastructure
install_ca_to_nss() {
  if ! command -v certutil >/dev/null 2>&1; then
    echo "[entrypoint] certutil (libnss3-tools) не найден — пропускаем NSS импорт"
    return 0
  fi

  local nss_db_dir="${HOME:-/root}/.pki/nssdb"
  local nss_db="sql:${nss_db_dir}"

  # CA certs могут быть в llm/ или custom/
  local target_dirs=(
    "/usr/local/share/ca-certificates/llm"
    "/usr/local/share/ca-certificates/custom"
  )

  # Собираем все PEM-файлы
  local certs=()
  for dir in "${target_dirs[@]}"; do
    if [ -d "$dir" ]; then
      shopt -s nullglob
      for f in "$dir"/*.pem "$dir"/*.crt; do
        certs+=("$f")
      done
      shopt -u nullglob
    fi
  done

  if [ ${#certs[@]} -eq 0 ]; then
    echo "[entrypoint] Нет PEM-файлов для NSS импорта — пропускаем"
    return 0
  fi

  # Создаём NSS DB если нет или если не открывается
  if [ ! -d "$nss_db_dir" ]; then
    mkdir -p "$nss_db_dir"
    echo "[entrypoint] Создание NSS DB: ${nss_db}"
    certutil -N -d "$nss_db" --empty-password 2>/dev/null || true
  elif ! certutil -L -d "$nss_db" >/dev/null 2>&1; then
    # DB существует но повреждена / неверный формат
    echo "[entrypoint] NSS DB повреждена, пересоздаём..."
    rm -f "${nss_db_dir}"/*.db "${nss_db_dir}"/pkcs11.txt 2>/dev/null || true
    certutil -N -d "$nss_db" --empty-password 2>/dev/null || true
  fi

  # Проверяем что DB работает
  if ! certutil -L -d "$nss_db" >/dev/null 2>&1; then
    echo "[entrypoint] ⚠ NSS DB не создалась — пропускаем"
    return 0
  fi

  local imported=0
  for cert in "${certs[@]}"; do
    local fingerprint
    fingerprint="$(openssl x509 -in "$cert" -noout -fingerprint -sha256 2>/dev/null | sed 's/.*=//' || true)"
    [ -z "$fingerprint" ] && continue

    # Используем директорию как префикс для nickname
    local dir_prefix
    dir_prefix="$(basename "$(dirname "$cert")")"
    local nickname="${dir_prefix}-$(basename "$cert" | sed 's/\.[^.]*$//')"

    # Дедупликация по fingerprint (не по nickname)
    if certutil -L -d "$nss_db" 2>/dev/null | grep -qF "$fingerprint"; then
      echo "[entrypoint]   ✓ NSS: ${nickname} уже импортирован (fingerprint совпадает)"
      continue
    fi

    # Если nickname занят другим сертификатом — добавляем с уникальным именем
    local actual_nickname="$nickname"
    if certutil -L -d "$nss_db" -n "$actual_nickname" >/dev/null 2>&1; then
      actual_nickname="${nickname}-$(echo "$fingerprint" | cut -c1-8)"
    fi

    # Добавляем с trust-атрибутами "C,," (CA для TLS)
    if certutil -A -d "$nss_db" -n "$actual_nickname" -t "C,," -i "$cert" -a 2>/dev/null; then
      echo "[entrypoint]   ➕ NSS импортирован: ${actual_nickname}"
      imported=$((imported + 1))
    else
      echo "[entrypoint]   ⚠ NSS ошибка импорта: ${nickname}"
    fi
  done

  if [ "$imported" -gt 0 ]; then
    echo "[entrypoint] ✅ NSS: импортировано ${imported} сертификатов"
  fi
}
# #endregion docker.backend.entrypoint.install_ca_to_nss

# ======================================================================
#  wait_for_db — проверка доступности БД с retry
# ======================================================================
# #region docker.backend.entrypoint.wait_for_db [C:3] [TYPE Function]
# @BRIEF Проверяет доступность PostgreSQL с retry-логикой перед запуском миграций.
# @PRE DATABASE_URL установлен и указывает на валидный PostgreSQL.
# @POST Соединение с БД подтверждено (SELECT 1) или скрипт exit(1) после таймаута.
# @RATIONALE Без wait-for-db enterprise-деплой с внешним PostgreSQL падает
#   мгновенно — entrypoint интерпретирует connection refused как "пустая БД".
# @REJECTED Использование pg_isready напрямую отвергнуто — клиент psql может
#   отсутствовать в python:3.11-slim образе. SQLAlchemy-проверка универсальна.
wait_for_db() {
  local max_attempts="${DB_WAIT_ATTEMPTS:-30}"
  local delay="${DB_WAIT_DELAY:-2}"
  local attempt=0

  echo "[entrypoint] Waiting for database (max ${max_attempts} attempts, ${delay}s delay)..."
  while [ $attempt -lt $max_attempts ]; do
    attempt=$((attempt + 1))
    # Capture stderr to detect permanent errors (KeyError, ArgumentError)
    local _err_output
    _err_output="$(python3 -c "
import os, sys
from sqlalchemy import create_engine, text
try:
    url = os.environ['DATABASE_URL']
except KeyError:
    print('FATAL: DATABASE_URL environment variable is not set', file=sys.stderr)
    sys.exit(99)
try:
    e = create_engine(url)
    with e.connect() as c:
        c.execute(text('SELECT 1'))
except Exception as exc:
    # Permanent errors — no point retrying
    err_str = str(exc).lower()
    if 'database_url' in err_str or 'could not parse' in err_str or 'invalid' in err_str:
        print(f'FATAL: {exc}', file=sys.stderr)
        sys.exit(99)
    sys.exit(1)
" 2>&1)"
    local _rc=$?

    if [ $_rc -eq 0 ]; then
      echo "[entrypoint] ✅ Database is reachable"
      return 0
    fi

    # Permanent error — exit immediately, don't waste retries
    if [ $_rc -eq 99 ]; then
      echo "[entrypoint] ❌ $_err_output" >&2
      return 1
    fi

    echo "[entrypoint]   Attempt ${attempt}/${max_attempts} — retrying in ${delay}s..."
    sleep "$delay"
  done

  # P0: Mask credentials — never print full DATABASE_URL to logs
  local _masked_url
  _masked_url="$(echo "$DATABASE_URL" | sed -E 's|://([^:]+):([^@]+)@|://\1:***@|')"
  echo "[entrypoint] ❌ Database not reachable after ${max_attempts} attempts" >&2
  echo "[entrypoint]   DATABASE_URL=${_masked_url}" >&2
  return 1
}
# #endregion docker.backend.entrypoint.wait_for_db

# ======================================================================
#  MAIN
# ======================================================================

install_certificates
install_llm_ca_certs
install_ca_to_nss

# ── C1: Wait for database before any migration logic ──
wait_for_db

# ── C2: DB state detection (now safe — DB is confirmed reachable) ──
_db_state=0
python3 -c "
import os
from sqlalchemy import create_engine, inspect
e = create_engine(os.environ['DATABASE_URL'])
insp = inspect(e)
if 'alembic_version' in insp.get_table_names():
    exit(0)
if not insp.get_table_names():
    exit(1)
exit(2)
" 2>&1 || _db_state=$?

if [ $_db_state -eq 0 ]; then
  echo "[entrypoint] Running Alembic migrations (incremental)..."
  alembic upgrade head 2>&1 | sed 's/^/[entrypoint]   /'
  echo "[entrypoint] ✅ Alembic migrations applied"
elif [ $_db_state -eq 1 ]; then
  echo "[entrypoint] Empty database — running full Alembic upgrade..."
  alembic upgrade head 2>&1 | sed 's/^/[entrypoint]   /'
  echo "[entrypoint] ✅ Alembic initial migration applied"
else
  echo "[entrypoint] Legacy database — running Alembic upgrade (not stamp)..."
  # H2: Запускаем полноценный upgrade вместо stamp head — legacy-БД может
  # отсутствовать таблицы, добавленные миграциями после написания entrypoint.
  alembic upgrade head 2>&1 | sed 's/^/[entrypoint]   /'
  echo "[entrypoint] ✅ Alembic upgrade complete for legacy database"
fi

bootstrap_admin

echo "[entrypoint] Starting backend: $*"
exec "$@"
