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

# Uso:
#   ./mysqlsh_backup_hardened.sh <OUT_DIR> <DATABASE> [EXCLUDE_TABLES]
# Ejemplo:
#   ./mysqlsh_backup_hardened.sh /backups mbinv "'mbinv.tmp1','mbinv.tmp2'"
# Opcional:
#   MYSQL_CNF=/ruta/credenciales.cnf ./mysqlsh_backup_hardened.sh /backups mbinv

OUT_DIR="${1:-}"
DATABASE="${2:-}"
EXCLUDE_TABLES="${3:-}"

if [[ -z "$OUT_DIR" || -z "$DATABASE" ]]; then
  echo "Uso: $0 <OUT_DIR> <DATABASE> [EXCLUDE_TABLES]"
  echo "Ej:  $0 /backups mbinv \"'mbinv.tmp1','mbinv.tmp2'\""
  exit 1
fi

# Configuracion de conexion (forzada por defecto, sobreescribible por env/.cnf)
DB_USER="${DB_USER:-manuel}"
DB_PASSWORD="${DB_PASSWORD:-Manuel$123}"
DB_HOST="${DB_HOST:-132.226.40.48}"
DB_PORT="${DB_PORT:-3310}"

# Archivo opcional de credenciales estilo ini:
# [client]
# user=...
# password=...
# host=...
# port=...
MYSQL_CNF="${MYSQL_CNF:-}"

if [[ -n "$MYSQL_CNF" ]]; then
  if [[ ! -f "$MYSQL_CNF" ]]; then
    echo "Error: MYSQL_CNF no existe: $MYSQL_CNF"
    exit 1
  fi
  # Si existen en el archivo, sobreescriben defaults.
  DB_USER="$(awk -F= '/^[[:space:]]*user[[:space:]]*=/{gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' "$MYSQL_CNF" || true)"
  DB_PASSWORD="$(awk -F= '/^[[:space:]]*password[[:space:]]*=/{gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' "$MYSQL_CNF" || true)"
  DB_HOST="$(awk -F= '/^[[:space:]]*host[[:space:]]*=/{gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' "$MYSQL_CNF" || true)"
  DB_PORT="$(awk -F= '/^[[:space:]]*port[[:space:]]*=/{gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' "$MYSQL_CNF" || true)"
fi

if [[ -z "$DB_USER" || -z "$DB_PASSWORD" || -z "$DB_HOST" || -z "$DB_PORT" ]]; then
  echo "Error: faltan credenciales/host/puerto para conexion MySQL"
  exit 1
fi

# Validacion de destino esperado
EXPECTED_HOST="$DB_HOST"
EXPECTED_PORT="$DB_PORT"

# Evitar herencia de variables de entorno que alteren conexion
unset MYSQL_PWD MYSQL_USER MYSQL_HOST MYSQL_TCP_PORT MYSQL_UNIX_PORT
unset MYSQLX_PWD MYSQLX_USER MYSQLX_HOST MYSQLX_TCP_PORT
unset MYSQLSH_USER MYSQLSH_PASSWORD MYSQLSH_URI

export TZ="America/Guatemala"
DATE_TAG="$(date +%Y%m%d_%H%M%S)"
TARGET_DIR="${OUT_DIR%/}/${DATABASE}_${DATE_TAG}"
PROGRESS_FILE="/tmp/dump-progress-${DATABASE}.json"

mkdir -p "$TARGET_DIR"

echo "Backup forzado hacia: ${DB_USER}@${DB_HOST}:${DB_PORT}"
echo "Base: $DATABASE"
echo "Destino dump: $TARGET_DIR"

CHECK_CMD="
var r=session.runSql(\"select user(), @@hostname, @@port\").fetchOne();
print('Conectado como: ' + r[0] + ' | Host DB: ' + r[1] + ' | Puerto DB: ' + r[2]);
if (String(r[1]) !== '${EXPECTED_HOST}' || String(r[2]) !== '${EXPECTED_PORT}') {
  throw new Error('Conexion inesperada: host/puerto no coinciden con destino forzado');
}
"

mysqlsh --js \
  --uri="${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}" \
  --execute "$CHECK_CMD"

if [[ -z "$EXCLUDE_TABLES" ]]; then
  DUMP_CMD="util.dumpSchemas(['$DATABASE'], '$TARGET_DIR', {
    'threads': 16,
    'showProgress': true,
    'compatibility': ['strip_definers'],
    'ocimds': false,
    'compression': 'zstd',
    'chunking': true,
    'consistent': true,
    'events': true,
    'routines': true,
    'triggers': true,
    'users': false,
    'progressFile': '$PROGRESS_FILE'
  })"
else
  DUMP_CMD="util.dumpSchemas(['$DATABASE'], '$TARGET_DIR', {
    'threads': 16,
    'showProgress': true,
    'compatibility': ['strip_definers'],
    'ocimds': false,
    'compression': 'zstd',
    'chunking': true,
    'consistent': true,
    'events': true,
    'routines': true,
    'triggers': true,
    'users': false,
    'excludeTables': [$EXCLUDE_TABLES],
    'progressFile': '$PROGRESS_FILE'
  })"
fi

echo "Ejecutando dump..."
mysqlsh --js \
  --uri="${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}" \
  --execute "$DUMP_CMD"

echo "Backup finalizado: $TARGET_DIR"
