#!/usr/bin/env bash
# BEGIN CHANGE: deploy do portal no servidor (git pull + build + publicar out/api)
# Repo clone: /home/ubuntu/www/html
# Runtime:    /home/ubuntu/{dev-portal,test-portal,beta-portal,portal}
#
# Uso:
#   ./deploy/deploy.sh --pull prod
#   ./deploy/deploy.sh --pull prod --skip-mirror
#   ./deploy/deploy.sh --pull dev
#   ./deploy/deploy.sh --pull all
#   ./deploy/deploy.sh prod --api-only          # so PHP, sem rebuild do front
#
# GitHub Actions chama: deploy.sh --pull prod

set -euo pipefail

REPO_ROOT="${WA_HTML_REPO:-/home/ubuntu/www/html}"
PORTAL_DIR="$REPO_ROOT/portal"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

export NVM_DIR="${NVM_DIR:-/root/.nvm}"
if [ -s "$NVM_DIR/nvm.sh" ]; then
  # shellcheck source=/dev/null
  . "$NVM_DIR/nvm.sh"
fi

TARGET="prod"
DO_PULL=false
API_ONLY=false
SKIP_MIRROR=false

usage() {
  cat <<'EOF'
Uso: deploy.sh [opcoes] [dev|test|beta|prod|all]

Opcoes:
  --pull         git pull --ff-only origin master antes do deploy
  --api-only     copia so api/*.php (sem npm build)
  --skip-mirror  com prod, nao espelha test/beta
  -h, --help     esta ajuda
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --pull) DO_PULL=true; shift ;;
    --api-only) API_ONLY=true; shift ;;
    --skip-mirror) SKIP_MIRROR=true; shift ;;
    -h|--help) usage; exit 0 ;;
    dev|test|beta|prod|all) TARGET="$1"; shift ;;
    *) echo "Opcao desconhecida: $1" >&2; usage; exit 1 ;;
  esac
done

# BEGIN CHANGE: serializar deploys (evita npm ci paralelo corrompendo node_modules)
LOCK_FILE="${WA_DEPLOY_LOCK:-/tmp/wa-portal-deploy.lock}"
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "==> Outro deploy em andamento; aguardando $LOCK_FILE ..."
  flock 9
fi
# END CHANGE

require_node() {
  if ! command -v node >/dev/null 2>&1; then
    echo "ERRO: Node nao encontrado. Rode: bash $SCRIPT_DIR/setup-node.sh" >&2
    exit 1
  fi
  local major
  major="$(node -p "process.versions.node.split('.')[0]")"
  if [ "$major" -lt 20 ]; then
    echo "ERRO: Node $(node -v) e antigo; precisa >= 20. Rode setup-node.sh" >&2
    exit 1
  fi
}

do_git_pull() {
  echo "==> git pull em $REPO_ROOT"
  cd "$REPO_ROOT"
  if [ -f /root/.ssh/github_pedro ]; then
    export GIT_SSH_COMMAND='ssh -i /root/.ssh/github_pedro -o IdentitiesOnly=yes'
  fi
  git fetch origin master
  if ! git diff --quiet || ! git diff --cached --quiet; then
    echo "==> Alteracoes locais detectadas; git stash push -u -m deploy-autostash"
    git stash push -u -m deploy-autostash || true
    STASHED=1
  else
    STASHED=0
  fi
  git merge --ff-only FETCH_HEAD
  if [ "${STASHED:-0}" = "1" ]; then
    git stash pop || echo "AVISO: git stash pop falhou; veja git stash list"
  fi
  # BEGIN CHANGE: nao deixar stash local sobrescrever scripts de deploy do repo
  git checkout HEAD -- portal/deploy/deploy.sh portal/deploy/setup-node.sh 2>/dev/null || true
  chmod +x portal/deploy/deploy.sh portal/deploy/setup-node.sh 2>/dev/null || true
  # END CHANGE
  echo "==> HEAD: $(git log -1 --oneline)"
}

target_root() {
  case "$1" in
    dev)  echo "/home/ubuntu/dev-portal" ;;
    test) echo "/home/ubuntu/test-portal" ;;
    beta) echo "/home/ubuntu/beta-portal" ;;
    prod) echo "/home/ubuntu/portal" ;;
    *) echo "Target invalido: $1" >&2; exit 1 ;;
  esac
}

target_env_id() {
  case "$1" in
    dev)  echo "dev" ;;
    test) echo "test" ;;
    beta) echo "beta" ;;
    prod) echo "prod" ;;
  esac
}

target_env_label() {
  case "$1" in
    test) echo "TEST" ;;
    beta) echo "BETA" ;;
    *)    echo "" ;;
  esac
}

ensure_runtime_dirs() {
  local root="$1"
  mkdir -p "$root/out" "$root/api" "$root/cache"
  chmod a+rX "$root" "$root/api" "$root/cache" 2>/dev/null || true
  chown -R www-data:www-data "$root/cache" 2>/dev/null || true

  if [ ! -f "$root/secret.key" ]; then
    echo "==> Criando secret.key em $root"
    openssl rand -hex 32 > "$root/secret.key"
    chmod 600 "$root/secret.key"
  fi
  chmod 644 "$root/secret.key" 2>/dev/null || true
  chown www-data:www-data "$root/secret.key" 2>/dev/null || true

  if [ ! -f "$root/env.php" ]; then
    echo "==> AVISO: $root/env.php ausente - copie de portal/deploy/env.example.php"
  else
    chmod 644 "$root/env.php" 2>/dev/null || true
    chown www-data:www-data "$root/env.php" 2>/dev/null || true
  fi
}

deploy_api() {
  local root="$1"
  echo "==> API PHP -> $root/api"
  mkdir -p "$root/api"
  cp -f "$PORTAL_DIR/api/"*.php "$root/api/"
  chmod a+r "$root/api/"*.php
}

deploy_front() {
  local t="$1"
  local root
  root="$(target_root "$t")"
  local env_id env_label

  env_id="$(target_env_id "$t")"
  env_label="$(target_env_label "$t")"

  echo "==> Build front: target=$t ($root)"
  cd "$PORTAL_DIR"
  export NEXT_PUBLIC_ENV_ID="$env_id"
  export NEXT_PUBLIC_ENV_LABEL="$env_label"

  # BEGIN CHANGE: limpar install parcial (ENOTEMPTY / @swc/helpers MODULE_NOT_FOUND)
  echo "==> npm ci (node_modules limpo)"
  rm -rf node_modules .next
  npm ci
  # END CHANGE

  npm run build
  if [ ! -f out/index.html ]; then
    echo "ERRO: build nao gerou out/index.html" >&2
    exit 1
  fi

  echo "==> Publicando out/ -> $root/out"
  mkdir -p "$root/out"
  rsync -a --delete "$PORTAL_DIR/out/" "$root/out/"
  chmod -R a+rX "$root/out"
}

deploy_target() {
  local t="$1"
  local root
  root="$(target_root "$t")"

  echo ""
  echo "========================================"
  echo " Deploy: $t -> $root"
  echo "========================================"

  ensure_runtime_dirs "$root"
  deploy_api "$root"

  if [ "$API_ONLY" = true ]; then
    echo "==> --api-only: pulando build do front"
    return 0
  fi

  require_node
  deploy_front "$t"
  echo "==> Concluido: $t"
}

if [ "$DO_PULL" = true ]; then
  do_git_pull
fi

if [ ! -d "$PORTAL_DIR" ]; then
  echo "ERRO: pasta portal nao encontrada em $PORTAL_DIR" >&2
  exit 1
fi

case "$TARGET" in
  all)
    for t in dev test beta prod; do
      deploy_target "$t"
    done
    ;;
  prod)
    deploy_target prod
    if [ "$SKIP_MIRROR" = false ] && [ "$API_ONLY" = false ]; then
      deploy_target test
      deploy_target beta
    elif [ "$SKIP_MIRROR" = false ] && [ "$API_ONLY" = true ]; then
      deploy_api "$(target_root test)"
      deploy_api "$(target_root beta)"
    fi
    ;;
  *)
    deploy_target "$TARGET"
    ;;
esac

echo ""
echo "==> Deploy finalizado ($TARGET)"
# END CHANGE
