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

# Uso:
#   ./mysqlsh_restore_hardened.sh <DUMP_DIR> <DATABASE> [EXCLUDE_TABLES] [SKIP_VIEWS_TRIGGERS]
# Ejemplo:
#   ./mysqlsh_restore_hardened.sh /backups/mbinv_20260602_010000 mbinv "" 1
# Opcional:
#   MYSQL_CNF=/ruta/credenciales.cnf ./mysqlsh_restore_hardened.sh /backups/mbinv_20260602_010000 mbinv "" 1

DUMP_DIR="${1:-}"
DATABASE="${2:-}"
EXCLUDE_TABLES="${3:-}"
SKIP_VIEWS_TRIGGERS="${4:-0}"  # 1 = omitir vistas y triggers

if [[ -z "$DUMP_DIR" || -z "$DATABASE" ]]; then
  echo "Uso: $0 <DUMP_DIR> <DATABASE> [EXCLUDE_TABLES] [SKIP_VIEWS_TRIGGERS]"
  echo "Ej:  $0 /backups/mbinv_20260602_010000 mbinv \"\" 1"
  exit 1
fi

if [[ ! -d "$DUMP_DIR" ]]; then
  echo "Error: no existe el directorio de dump: $DUMP_DIR"
  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"
TARGET_DB="$DATABASE"
PROGRESS_FILE="/tmp/load-progress-${TARGET_DB}.json"

WORK_DIR="/tmp/load_dump_${TARGET_DB}"
rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR"

echo "Restore forzado hacia: ${DB_USER}@${DB_HOST}:${DB_PORT}"
echo "Dump origen: $DUMP_DIR"
echo "Base destino: $TARGET_DB"

echo "Copiando dump a area temporal: $WORK_DIR"
cp -a "$DUMP_DIR"/. "$WORK_DIR"/

# Sanitizar DEFINER y usar INVOKER
find "$WORK_DIR" -type f -name "*.sql" -exec sed -i -E \
  -e 's/\/\*![0-9]{5} DEFINER=`[^`]+`@`[^`]+` \*\//\/* stripped DEFINER *\//g' \
  -e 's/DEFINER=`[^`]+`@`[^`]+`[ ]*//g' \
  -e 's/SQL SECURITY DEFINER/SQL SECURITY INVOKER/g' {} +

if [[ "$SKIP_VIEWS_TRIGGERS" == "1" ]]; then
  echo "Omitiendo vistas y triggers (SKIP_VIEWS_TRIGGERS=1)..."
  find "$WORK_DIR" -type f -name "*.sql" -exec sed -i -E \
    -e '/^-- begin trigger /,/^-- end trigger /d' \
    -e '/^-- begin view /,/^-- end view /d' {} +
fi

MYSQL_PWD="$DB_PASSWORD" mysql \
  -h "$DB_HOST" -u "$DB_USER" -P "$DB_PORT" \
  -e "DROP DATABASE IF EXISTS \`$TARGET_DB\`; CREATE DATABASE \`$TARGET_DB\`;"

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
  LOAD_CMD="util.loadDump('$WORK_DIR', {
    'ignoreVersion': true,
    'resetProgress': true,
    'threads': 32,
    'loadDdl': true,
    'loadData': true,
    'schema': '$TARGET_DB',
    'progressFile': '$PROGRESS_FILE',
    'showProgress': true
  })"
else
  LOAD_CMD="util.loadDump('$WORK_DIR', {
    'ignoreVersion': true,
    'resetProgress': true,
    'threads': 32,
    'loadDdl': true,
    'loadData': true,
    'excludeTables': [$EXCLUDE_TABLES],
    'schema': '$TARGET_DB',
    'progressFile': '$PROGRESS_FILE',
    'showProgress': true
  })"
fi

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

echo "Restore finalizado: $TARGET_DB"
rm -rf "$WORK_DIR"
