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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

SOURCE_HOST="${SOURCE_HOST:-}"
SOURCE_PORT="${SOURCE_PORT:-3306}"
SOURCE_DATABASE="${SOURCE_DATABASE:-}"
SOURCE_USER="${SOURCE_USER:-}"
SOURCE_PASSWORD="${SOURCE_PASSWORD:-}"

TARGET_SERVICE="${TARGET_SERVICE:-mysql-debug}"
TARGET_DATABASE="${TARGET_DATABASE:-}"
TARGET_USER="${TARGET_USER:-}"
TARGET_PASSWORD="${TARGET_PASSWORD:-}"

FORCE="${FORCE:-0}"

if [[ -f ".env" ]]; then
  # shellcheck disable=SC2046
  export $(grep -E '^[A-Za-z_][A-Za-z0-9_]*=' .env | sed 's/\r$//')
fi

SOURCE_HOST="${SOURCE_HOST:-${CONFIG_DB_HOST:-}}"
SOURCE_DATABASE="${SOURCE_DATABASE:-${CONFIG_DB_DATABASE:-}}"
SOURCE_USER="${SOURCE_USER:-${CONFIG_DB_USER:-}}"
SOURCE_PASSWORD="${SOURCE_PASSWORD:-${CONFIG_DB_PASSWORD:-}}"

TARGET_DATABASE="${TARGET_DATABASE:-${CONFIG_DB_DEBUG_DATABASE:-}}"
TARGET_USER="${TARGET_USER:-${CONFIG_DB_DEBUG_USER:-}}"
TARGET_PASSWORD="${TARGET_PASSWORD:-${CONFIG_DB_DEBUG_PASSWORD:-}}"

if [[ -z "${SOURCE_HOST}" || -z "${SOURCE_DATABASE}" || -z "${SOURCE_USER}" || -z "${SOURCE_PASSWORD}" ]]; then
  echo "Missing live DB credentials. Expected CONFIG_DB_HOST/CONFIG_DB_DATABASE/CONFIG_DB_USER/CONFIG_DB_PASSWORD."
  exit 1
fi
if [[ -z "${TARGET_DATABASE}" || -z "${TARGET_USER}" || -z "${TARGET_PASSWORD}" ]]; then
  echo "Missing debug DB credentials. Expected CONFIG_DB_DEBUG_DATABASE/CONFIG_DB_DEBUG_USER/CONFIG_DB_DEBUG_PASSWORD."
  exit 1
fi

if ! command -v docker >/dev/null 2>&1; then
  echo "Docker is required but was not found in PATH."
  exit 1
fi

if [[ "${FORCE}" != "1" ]]; then
  echo "This will overwrite debug DB '${TARGET_DATABASE}' in service '${TARGET_SERVICE}' with live DB '${SOURCE_DATABASE}' from '${SOURCE_HOST}'."
  read -r -p "Type CLONE to continue: " confirmation
  if [[ "${confirmation}" != "CLONE" ]]; then
    echo "Cancelled."
    exit 1
  fi
fi

echo "Starting debug DB service (${TARGET_SERVICE})..."
docker compose up -d "${TARGET_SERVICE}"

echo "Waiting for debug DB to accept connections..."
for i in $(seq 1 60); do
  if docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysqladmin -u '${TARGET_USER}' ping --silent" >/dev/null 2>&1; then
    break
  fi
  if [[ "$i" -eq 60 ]]; then
    echo "Timed out waiting for ${TARGET_SERVICE} to become ready."
    exit 1
  fi
  sleep 2
done

DUMP_DIR="${ROOT_DIR}/.tmp-db-clone"
DUMP_FILE="${DUMP_DIR}/live-to-debug.sql"
mkdir -p "${DUMP_DIR}"
rm -f "${DUMP_FILE}"

echo "Creating live dump..."
docker run --rm \
  -e "MYSQL_PWD=${SOURCE_PASSWORD}" \
  -v "${DUMP_DIR}:/dump" \
  mysql:8.4 \
  sh -lc "exec mysqldump --compression-algorithms=zstd --single-transaction --quick --set-gtid-purged=OFF -h '${SOURCE_HOST}' -P '${SOURCE_PORT}' -u '${SOURCE_USER}' '${SOURCE_DATABASE}' > /dump/live-to-debug.sql"

if [[ ! -f "${DUMP_FILE}" ]]; then
  echo "Database dump failed."
  exit 1
fi

echo "Resetting debug database '${TARGET_DATABASE}'..."
docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysql -u '${TARGET_USER}' -e \"DROP DATABASE IF EXISTS ${TARGET_DATABASE}; CREATE DATABASE ${TARGET_DATABASE};\""

echo "Importing live dump into debug DB..."
cat "${DUMP_FILE}" | docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysql -u '${TARGET_USER}' '${TARGET_DATABASE}'"

rm -f "${DUMP_FILE}"
echo "Done. Debug DB '${TARGET_DATABASE}' now mirrors live '${SOURCE_DATABASE}'."
