#!/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:-}"
DUMP_OCIMDS="${DUMP_OCIMDS:-0}"
DUMP_COMPRESSION="${DUMP_COMPRESSION:-zstd}"

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:-}"
MYSQLSH_BIN="${MYSQLSH_BIN:-mysqlsh}"

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

if [[ "$DUMP_OCIMDS" != "0" && "$DUMP_OCIMDS" != "1" ]]; then
  echo "Error: DUMP_OCIMDS debe ser 0 o 1"
  exit 1
fi

if [[ "$DUMP_COMPRESSION" != "zstd" && "$DUMP_COMPRESSION" != "none" ]]; then
  echo "Error: DUMP_COMPRESSION debe ser zstd o none"
  exit 1
fi

if ! command -v "$MYSQLSH_BIN" >/dev/null 2>&1; then
  echo "Error: no se encontro MYSQLSH_BIN=$MYSQLSH_BIN"
  exit 1
fi

# 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('Endpoint solicitado: ${DB_HOST}:${DB_PORT}');
print('Conectado como: ' + r[0] + ' | Host DB reportado: ' + r[1] + ' | Puerto DB reportado: ' + r[2]);
if (String(r[0]).split('@')[0] !== '${DB_USER}') {
  throw new Error('Conexion inesperada: usuario autenticado no coincide con el destino forzado');
}
"

"$MYSQLSH_BIN" --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': $( [[ "$DUMP_OCIMDS" == "1" ]] && echo true || echo false ),
    'compression': '$DUMP_COMPRESSION',
    'chunking': true,
    'consistent': true,
    'events': true,
    'routines': true,
    'triggers': true
  })"
else
  DUMP_CMD="util.dumpSchemas(['$DATABASE'], '$TARGET_DIR', {
    'threads': 16,
    'showProgress': true,
    'compatibility': ['strip_definers'],
    'ocimds': $( [[ "$DUMP_OCIMDS" == "1" ]] && echo true || echo false ),
    'compression': '$DUMP_COMPRESSION',
    'chunking': true,
    'consistent': true,
    'events': true,
    'routines': true,
    'triggers': true,
    'excludeTables': [$EXCLUDE_TABLES]
  })"
fi

echo "Ejecutando dump con DUMP_OCIMDS=$DUMP_OCIMDS y DUMP_COMPRESSION=$DUMP_COMPRESSION..."
"$MYSQLSH_BIN" --js \
  --uri="${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}" \
  --execute "$DUMP_CMD"

echo "Backup finalizado: $TARGET_DIR"
