#!/bin/bash
# ============================================================
# deploy.sh — Script de deploy do OnSMS em servidor próprio
# ============================================================
# Uso: bash deploy.sh
#
# Pré-requisitos no servidor:
#   - Node.js >= 20, npm, PM2 instalados
#   - Arquivo .env configurado na raiz do projeto
#   - Banco PostgreSQL rodando e DATABASE_URL configurada
# ============================================================

set -e

EXPECTED_DIR="/home/onsmscom/portal.onsms.com.br/portalonsms2"
if [ "$(pwd)" != "$EXPECTED_DIR" ]; then
  echo "ERRO: deploy.sh deve ser executado em $EXPECTED_DIR (produção). Abortando." >&2
  echo "Rodando em: $(pwd)" >&2
  exit 1
fi

echo "==> [1/7] Atualizando código do repositório..."
# Descarta um possível package-lock.json regenerado em deploy anterior para que o
# git pull não falhe com "local changes would be overwritten".
git checkout -- package-lock.json 2>/dev/null || true
git pull origin main

echo "==> [2/7] Instalando dependências..."
# O package-lock.json versionado pode conter URLs do registry interno do Replit
# (package-firewall.replit.local), que não existe neste servidor. Removemos o lockfile
# e instalamos sempre do registry público para evitar erros de instalação.
rm -f package-lock.json
npm install --production=false --registry https://registry.npmjs.org/

echo "==> [3/7] Aplicando schema do banco (db:push)..."
export $(grep -v '^#' .env | xargs)
# Blindagem (16/07/2026): abortar o prompt de data-loss do drizzle-kit sai
# com exit 0 — sem esta checagem o deploy SEGUIRIA e reiniciaria o app com o
# schema possivelmente não aplicado (app novo + banco velho). O `script` dá
# um pty ao drizzle (o prompt interativo continua funcionando normalmente)
# e grava a saída; se o operador abortou, o deploy PARA aqui, antes do
# build/restart — a produção continua na versão anterior, intacta.
DBPUSH_LOG=$(mktemp)
script -qec "npm run db:push" "$DBPUSH_LOG"
if grep -q "All changes were aborted" "$DBPUSH_LOG"; then
  rm -f "$DBPUSH_LOG"
  echo "" >&2
  echo "ERRO: o db:push foi ABORTADO no prompt — deploy interrompido." >&2
  echo "A aplicação NÃO foi rebuildada nem reiniciada (segue na versão anterior)." >&2
  echo "Revise a mudança de schema recusada e rode 'bash deploy.sh' de novo." >&2
  exit 1
fi
rm -f "$DBPUSH_LOG"

echo "==> [4/7] Aplicando migrations SQL pendentes (backfills de dados)..."
# O db:push acima cobre só ESTRUTURA (colunas/tabelas do shared/schema.ts).
# Migrations com UPDATE/backfill de dados (ex.: 036, 037) precisam dos arquivos
# de migrations/*.sql. Este passo roda cada arquivo AINDA NÃO aplicado, uma
# única vez, registrando na tabela de controle onsms_data_migrations (a mesma
# do seed/Task #208) com a chave "sqlfile:<arquivo>".
#
# BASELINE: arquivos com número < MIGRATIONS_BASELINE são apenas registrados,
# sem executar — a produção já os recebeu (via db:push/psql manual) e os
# antigos não são todos idempotentes. Só migrations novas (>= baseline) rodam.
MIGRATIONS_BASELINE=35
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -q -c "
  CREATE TABLE IF NOT EXISTS onsms_data_migrations (
    key varchar(128) PRIMARY KEY,
    applied_at timestamptz NOT NULL DEFAULT now()
  )"
for f in migrations/[0-9]*.sql; do
  [ -e "$f" ] || continue
  fname="$(basename "$f")"
  key="sqlfile:$fname"
  num=$((10#$(echo "$fname" | grep -oE '^[0-9]+')))
  applied=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM onsms_data_migrations WHERE key = '$key'")
  if [ "$applied" = "1" ]; then
    continue
  fi
  if [ "$num" -lt "$MIGRATIONS_BASELINE" ]; then
    # Baseline: registra como aplicada sem executar (histórico pré-runner).
    psql "$DATABASE_URL" -q -c "INSERT INTO onsms_data_migrations (key) VALUES ('$key') ON CONFLICT (key) DO NOTHING"
    continue
  fi
  echo "    -> aplicando $fname"
  psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f "$f"
  psql "$DATABASE_URL" -q -c "INSERT INTO onsms_data_migrations (key) VALUES ('$key') ON CONFLICT (key) DO NOTHING"
done

# Rede de segurança dos índices críticos (16/07/2026): o db:push do passo 3
# pode DROPAR índices que não constam do schema Drizzle (aconteceu — 12
# índices de MO/webhook/Alta Vazão sumiram da produção num deploy). Este
# arquivo roda em TODO deploy e recria o que faltar (IF NOT EXISTS = no-op
# no caminho normal; CONCURRENTLY = sem bloquear writes em tabela grande).
echo "    -> garantindo índices críticos (migrations/always/ensure_indexes.sql)"
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -q -f migrations/always/ensure_indexes.sql

echo "==> [5/7] Compilando o frontend (Vite build)..."
npm run build

echo "==> [6/7] Reiniciando aplicação via PM2..."
pm2 restart ecosystem.config.cjs || pm2 start ecosystem.config.cjs

echo "==> [7/7] Salvando lista de processos PM2..."
pm2 save

echo ""
echo "✔ Deploy concluído!"
echo "  Verifique os logs com: pm2 logs onsms"
