#!/usr/bin/env bash
#
# PLOCAL Phase 5I-B5 — safe, repeatable MySQL restore wrapper.
#
# Restores a backup produced by tools/plocal-db-backup.sh into an
# explicit, pre-existing, already-empty restore-target database. Never
# infers a target from application config; never drops or creates a
# database itself (this MySQL user is not granted CREATE/DROP DATABASE
# — the target must already exist, owned by an authorized administrator).
#
# Required environment variables:
#   PLOCAL_MYSQL_OPTION_FILE   path to a 0600 MySQL client option file
#   PLOCAL_RESTORE_DB          exact restore-target database name
#   PLOCAL_RESTORE_DUMP_FILE   path to the .sql.gz produced by the backup script
#
# Explicitly refused database names (never a valid PLOCAL_RESTORE_DB):
#   plocal_local, plocal_local_test
#
# Refuses to proceed unless the target database is currently empty (0
# tables) — this tool will never overwrite a database that already has
# schema/data in it.
#
# Usage:
#   PLOCAL_MYSQL_OPTION_FILE=/path/to/opts.cnf \
#   PLOCAL_RESTORE_DB=plocal_a4_restore_20260818 \
#   PLOCAL_RESTORE_DUMP_FILE=/path/to/backups/plocal_a4_cleanroom_20260818_TIMESTAMP.sql.gz \
#   tools/plocal-db-restore.sh

set -euo pipefail

if [[ -z "${PLOCAL_MYSQL_OPTION_FILE:-}" ]]; then
    echo "Refusing: PLOCAL_MYSQL_OPTION_FILE is not set." >&2
    exit 2
fi
if [[ ! -f "${PLOCAL_MYSQL_OPTION_FILE}" ]]; then
    echo "Refusing: PLOCAL_MYSQL_OPTION_FILE does not exist: ${PLOCAL_MYSQL_OPTION_FILE}" >&2
    exit 2
fi
option_file_mode="$(stat -c '%a' "${PLOCAL_MYSQL_OPTION_FILE}")"
if [[ "${option_file_mode}" != "600" ]]; then
    echo "Refusing: PLOCAL_MYSQL_OPTION_FILE must be mode 0600, found ${option_file_mode}." >&2
    exit 2
fi

if [[ -z "${PLOCAL_RESTORE_DB:-}" ]]; then
    echo "Refusing: PLOCAL_RESTORE_DB is not set (no default is ever assumed)." >&2
    exit 2
fi
case "${PLOCAL_RESTORE_DB}" in
    plocal_local|plocal_local_test)
        echo "Refusing: '${PLOCAL_RESTORE_DB}' is a protected database and may never be a restore target for this tool." >&2
        exit 2
        ;;
esac

if [[ -z "${PLOCAL_RESTORE_DUMP_FILE:-}" ]]; then
    echo "Refusing: PLOCAL_RESTORE_DUMP_FILE is not set." >&2
    exit 2
fi
if [[ ! -f "${PLOCAL_RESTORE_DUMP_FILE}" ]]; then
    echo "Refusing: dump file does not exist: ${PLOCAL_RESTORE_DUMP_FILE}" >&2
    exit 2
fi
checksum_file="${PLOCAL_RESTORE_DUMP_FILE}.sha256"
if [[ -f "${checksum_file}" ]]; then
    echo "Verifying checksum against ${checksum_file}..."
    (cd "$(dirname "${PLOCAL_RESTORE_DUMP_FILE}")" && sha256sum -c "$(basename "${checksum_file}")")
else
    echo "WARNING: no checksum file found alongside the dump; proceeding without verification." >&2
fi

existing_table_count="$(mysql --defaults-extra-file="${PLOCAL_MYSQL_OPTION_FILE}" -N -B \
    -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${PLOCAL_RESTORE_DB}'")"
if [[ "${existing_table_count}" -ne 0 ]]; then
    echo "Refusing: restore target '${PLOCAL_RESTORE_DB}' already has ${existing_table_count} table(s). This tool never overwrites a non-empty database — wipe it explicitly and separately first if that is really intended." >&2
    exit 2
fi

echo "Restoring ${PLOCAL_RESTORE_DUMP_FILE} -> '${PLOCAL_RESTORE_DB}'"
gunzip -c "${PLOCAL_RESTORE_DUMP_FILE}" | mysql --defaults-extra-file="${PLOCAL_MYSQL_OPTION_FILE}" "${PLOCAL_RESTORE_DB}"

restored_table_count="$(mysql --defaults-extra-file="${PLOCAL_MYSQL_OPTION_FILE}" -N -B \
    -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${PLOCAL_RESTORE_DB}'")"
if [[ "${restored_table_count}" -eq 0 ]]; then
    echo "FAIL: restore target has 0 tables after restore — treating as a failed restore." >&2
    exit 1
fi

echo "PASS: restore complete (${restored_table_count} tables present)."
