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

# ------------------------------------------------------------
# Hockey Web / Stat2TV deploy
# ------------------------------------------------------------

REPO_URL="https://git.tvstart.ru/ychernenko/hockey_new.git"
TARGET_DIR="/root/KHL"
SERVICE_NAME="khl-data.service"
ENV_FILE="/mnt/khl/.env"
PORT="8000"
RELEASE="main"

log()  { printf '\033[0;32m[INFO]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*" >&2; }
err()  { printf '\033[0;31m[ERROR]\033[0m %s\n' "$*" >&2; }

usage() {
  cat <<USAGE
Использование:
  sudo $0 [-r branch|tag|commit]

Примеры:
  sudo $0 -r main
  sudo $0 -r Barabanov_TEST
  sudo $0 -r v1.2.3
USAGE
}

while getopts ":r:h" opt; do
  case "$opt" in
    r) RELEASE="$OPTARG" ;;
    h) usage; exit 0 ;;
    :) err "Для -$OPTARG требуется значение"; exit 2 ;;
    \?) err "Неизвестный параметр: -$OPTARG"; usage; exit 2 ;;
  esac
done

if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
  err "Запусти deploy от root: sudo $0 -r $RELEASE"
  exit 1
fi

install_system_dependencies() {
  local missing=()
  for cmd in git python3 curl systemctl; do
    command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd")
  done

  if ! python3 -m venv --help >/dev/null 2>&1; then
    missing+=("python3-venv")
  fi

  if ((${#missing[@]} > 0)); then
    log "Устанавливаю системные зависимости: ${missing[*]}"
    apt-get update
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
      git python3 python3-venv python3-pip curl ca-certificates
  else
    log "Системные зависимости уже установлены"
  fi
}

check_env() {
  if [[ ! -f "$ENV_FILE" ]]; then
    err "Не найден файл окружения: $ENV_FILE"
    err "Создай его до deploy. Минимально нужны HOCKEY_DATABASE_URL и WFL_DATABASE_URL."
    exit 1
  fi
  chmod 600 "$ENV_FILE" || true
}

checkout_release() {
  if [[ -d "$TARGET_DIR/.git" ]]; then
    log "Обновляю существующий репозиторий в $TARGET_DIR"
    git -C "$TARGET_DIR" remote set-url origin "$REPO_URL"
    git -C "$TARGET_DIR" fetch origin --prune --tags
  else
    log "Клонирую $REPO_URL -> $TARGET_DIR"
    mkdir -p "$(dirname "$TARGET_DIR")"
    git clone "$REPO_URL" "$TARGET_DIR"
    git -C "$TARGET_DIR" fetch origin --prune --tags
  fi

  # Ветка origin/<release>
  if git -C "$TARGET_DIR" show-ref --verify --quiet "refs/remotes/origin/$RELEASE"; then
    log "Deploy ветки: $RELEASE"
    git -C "$TARGET_DIR" checkout -B "$RELEASE" "origin/$RELEASE"
    git -C "$TARGET_DIR" reset --hard "origin/$RELEASE"

  # Git tag
  elif git -C "$TARGET_DIR" show-ref --verify --quiet "refs/tags/$RELEASE"; then
    log "Deploy тега: $RELEASE"
    git -C "$TARGET_DIR" checkout --detach "refs/tags/$RELEASE"

  # SHA / локально разрешимый commit-ish
  elif git -C "$TARGET_DIR" rev-parse --verify --quiet "$RELEASE^{commit}" >/dev/null; then
    log "Deploy commit: $RELEASE"
    git -C "$TARGET_DIR" checkout --detach "$RELEASE"

  else
    err "Не найдена ветка, тег или commit: $RELEASE"
    echo ""
    echo "Удалённые ветки:"
    git -C "$TARGET_DIR" branch -r || true
    echo ""
    echo "Теги:"
    git -C "$TARGET_DIR" tag -l | tail -50 || true
    exit 1
  fi

  # Удаляем только обычные untracked-файлы. Игнорируемые .env/settings не трогаются.
  git -C "$TARGET_DIR" clean -fd

  log "Commit: $(git -C "$TARGET_DIR" log -1 --oneline)"
}

check_project_files() {
  local required=("app.py" "requirements.txt" "check_remote_database.py" "hockey_data/__init__.py" "ui_builder/__init__.py" "khl_site/khl_data_center.py")
  local f
  for f in "${required[@]}"; do
    if [[ ! -f "$TARGET_DIR/$f" ]]; then
      err "В релизе отсутствует обязательный файл: $f"
      exit 1
    fi
  done
}

prepare_env_link() {
  # Приложение само читает .env из корня проекта. Оставляем секреты вне Git,
  # но делаем ссылку, чтобы одинаково работал systemd и ручной запуск.
  if [[ -e "$TARGET_DIR/.env" && ! -L "$TARGET_DIR/.env" ]]; then
    warn "$TARGET_DIR/.env уже существует обычным файлом — оставляю его как есть"
  else
    ln -sfn "$ENV_FILE" "$TARGET_DIR/.env"
  fi
}

prepare_venv() {
  if [[ ! -x "$TARGET_DIR/.venv/bin/python" ]]; then
    log "Создаю virtualenv"
    python3 -m venv "$TARGET_DIR/.venv"
  fi

  log "Обновляю Python-зависимости"
  "$TARGET_DIR/.venv/bin/python" -m pip install --upgrade pip setuptools wheel
  "$TARGET_DIR/.venv/bin/python" -m pip install -r "$TARGET_DIR/requirements.txt"
}

validate_code() {
  log "Проверяю Python-код"
  "$TARGET_DIR/.venv/bin/python" -m py_compile \
    "$TARGET_DIR/app.py" \
    "$TARGET_DIR/check_remote_database.py"

  # Проверка БД тем же кодом, который использует проект.
  log "Проверяю PostgreSQL"
  (
    cd "$TARGET_DIR"
    "$TARGET_DIR/.venv/bin/python" "$TARGET_DIR/check_remote_database.py"
  )
}

write_systemd_service() {
  log "Создаю systemd unit: /etc/systemd/system/$SERVICE_NAME"

  cat > "/etc/systemd/system/$SERVICE_NAME" <<UNIT
[Unit]
Description=Hockey Stat2TV / UI Builder
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
User=root
WorkingDirectory=$TARGET_DIR
EnvironmentFile=$ENV_FILE
Environment=PYTHONUNBUFFERED=1
Environment=PYTHONDONTWRITEBYTECODE=1

# Перед стартом убеждаемся, что PostgreSQL доступен.
ExecStartPre=$TARGET_DIR/.venv/bin/python $TARGET_DIR/check_remote_database.py

# ГЛАВНАЯ КОМАНДА ЗАПУСКА ПРОЕКТА:
ExecStart=$TARGET_DIR/.venv/bin/python -m uvicorn app:app --host 0.0.0.0 --port $PORT

Restart=on-failure
RestartSec=5
TimeoutStopSec=20
KillSignal=SIGINT
StandardOutput=journal
StandardError=journal
SyslogIdentifier=KHL

[Install]
WantedBy=multi-user.target
UNIT

  chmod 644 "/etc/systemd/system/$SERVICE_NAME"
  systemctl daemon-reload
  systemctl enable "$SERVICE_NAME" >/dev/null
}

restart_service() {
  log "Перезапускаю $SERVICE_NAME"
  systemctl restart "$SERVICE_NAME"

  log "Жду HTTP на 127.0.0.1:$PORT"
  local ok=0
  for _ in $(seq 1 30); do
    if curl -fsS --max-time 2 "http://127.0.0.1:$PORT/api/hockey/database/status" >/tmp/khl-health.json 2>/dev/null; then
      ok=1
      break
    fi
    sleep 1
  done

  if [[ "$ok" -ne 1 ]]; then
    err "Приложение не прошло HTTP-проверку"
    systemctl status "$SERVICE_NAME" --no-pager -l || true
    echo ""
    journalctl -u "$SERVICE_NAME" -n 100 --no-pager || true
    exit 1
  fi

  log "HTTP OK: $(cat /tmp/khl-health.json)"
  rm -f /tmp/khl-health.json
}

main() {
  log "Deploy Hockey: release=$RELEASE"
  install_system_dependencies
  check_env
  checkout_release
  check_project_files

  # Не меняем активный venv, пока код ещё не скачан/проверен по структуре.
  systemctl stop "$SERVICE_NAME" 2>/dev/null || true

  prepare_env_link
  prepare_venv
  validate_code
  write_systemd_service
  restart_service

  echo ""
  log "Deploy завершён"
  log "Service: $SERVICE_NAME"
  log "URL: http://<SERVER_IP>:$PORT/"
  log "Status: systemctl status $SERVICE_NAME"
  log "Logs: journalctl -u $SERVICE_NAME -f"
  log "Restart: systemctl restart $SERVICE_NAME"
  echo ""
  log "Команда запуска приложения:"
  echo "  $TARGET_DIR/.venv/bin/python -m uvicorn app:app --host 0.0.0.0 --port $PORT"
}

main "$@"
