#!/bin/bash
set -euo pipefail

# ================================================================
# Restore script for mrt0rtikize.ru Matrix instance
# ================================================================
# Reads a backup directory created by backup-mrt0rtikize.sh
# and restores it to the new yandex-prod cluster.
#
# Usage: ./restore-mrt0rtikize.sh <backup-dir>
#
# Steps:
#   1. Scale Synapse + MAS to 0 on new cluster
#   2. Restore PostgreSQL dumps to CNPG shared-pg
#   3. Apply generated secrets (signing key, MAS keys, macaroon)
#   4. Apply deployment markers
#   5. Scale Synapse to 1 (now has signing key + DB)
#   6. Restore media files
#   7. Scale MAS to 1
# ================================================================

readonly YC_KUBECONFIG="${KUBECONFIG:-/home/mrt0rtikize/infra/yandex-prod/kubeconfig}"
readonly K="${KUBECTL:-kubectl} --kubeconfig ${YC_KUBECONFIG}"

readonly NS="matrix-mrt0rtikize"
readonly CNPG_NS="cnpg"
readonly CNPG_POD="shared-pg-1"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log()  { echo -e "${GREEN}[$(date +%H:%M:%S)]${NC} $*"; }
warn() { echo -e "${YELLOW}[$(date +%H:%M:%S)] WARN:${NC} $*"; }
err()  { echo -e "${RED}[$(date +%H:%M:%S)] ERROR:${NC} $*"; }

# -------------------------------------------------------------------
# Usage
# -------------------------------------------------------------------
if [ $# -ne 1 ]; then
    echo "Usage: $0 <backup-dir>"
    echo ""
    echo "Example: $0 backups/matrix-mrt0rtikize-20260613-192010/"
    exit 1
fi

readonly BACKUP_DIR="$1"

if [ ! -d "${BACKUP_DIR}" ]; then
    err "Backup directory not found: ${BACKUP_DIR}"
    exit 1
fi

# Verify critical files exist
for f in dump-synapse.sql dump-mas.sql secret-generated.yaml markers.yaml synapse-media.tar.gz; do
    if [ ! -f "${BACKUP_DIR}/${f}" ]; then
        warn "Missing: ${f}"
    fi
done

# -------------------------------------------------------------------
# Prerequisites
# -------------------------------------------------------------------
log "=== Checking prerequisites ==="

if ! ${K} get ns "${NS}" >/dev/null 2>&1; then
    err "Namespace ${NS} not found on new cluster. Deploy the ESS app first."
    exit 1
fi

if ! ${K} -n "${CNPG_NS}" get pod "${CNPG_POD}" >/dev/null 2>&1; then
    err "CNPG pod ${CNPG_POD} not found. Is the CNPG cluster running?"
    exit 1
fi

log "Cluster access verified."

# -------------------------------------------------------------------
# Step 1: Scale Synapse + MAS to 0
# -------------------------------------------------------------------
log "=== Step 1: Stopping Synapse + MAS ==="

${K} -n "${NS}" scale sts -l "app.kubernetes.io/component=matrix-server" --replicas=0 2>/dev/null || \
    ${K} -n "${NS}" scale sts "${NS}-synapse-main" --replicas=0 2>/dev/null || \
    warn "Could not scale Synapse via known names, trying by label..."

${K} -n "${NS}" scale deploy -l "app.kubernetes.io/component=matrix-authentication" --replicas=0 2>/dev/null || \
    ${K} -n "${NS}" scale deploy "${NS}-matrix-authentication-service" --replicas=0 2>/dev/null || \
    warn "Could not scale MAS via known names..."

log "Waiting for Synapse + MAS pods to terminate..."
${K} -n "${NS}" wait --for=delete pod -l "app.kubernetes.io/component=matrix-server" --timeout=120s 2>/dev/null || warn "Some Synapse pods may still be terminating."
${K} -n "${NS}" wait --for=delete pod -l "app.kubernetes.io/component=matrix-authentication" --timeout=120s 2>/dev/null || warn "Some MAS pods may still be terminating."

log "Synapse + MAS stopped."

# -------------------------------------------------------------------
# Step 2: Clean schemas (DROP SCHEMA CASCADE — no connection races)
# -------------------------------------------------------------------
log "=== Step 2: Cleaning database schemas ==="

log "Reading PG credentials from cluster..."
SYNAPSE_PW=$(${K} get secret pg-creds -n "${NS}" -o jsonpath='{.data.synapse}' | base64 -d)
MAS_PW=$(${K} get secret pg-creds -n "${NS}" -o jsonpath='{.data.mas}' | base64 -d)

log "Wiping synapse schema..."
${K} exec -n "${CNPG_NS}" "${CNPG_POD}" -- env PGPASSWORD="${SYNAPSE_PW}" \
    psql -U synapse_mrt0rtikize -d synapse_mrt0rtikize -h localhost -c \
    "DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO synapse_mrt0rtikize;" 2>/dev/null || true

log "Wiping MAS schema..."
${K} exec -n "${CNPG_NS}" "${CNPG_POD}" -- env PGPASSWORD="${MAS_PW}" \
    psql -U mas_mrt0rtikize -d mas_mrt0rtikize -h localhost -c \
    "DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO mas_mrt0rtikize;" 2>/dev/null || true

log "Schemas cleaned."

# -------------------------------------------------------------------
# Step 3: Restore PostgreSQL dumps
# -------------------------------------------------------------------
log "=== Step 3: Restoring PostgreSQL dumps ==="

log "Restoring Synapse database..."
${K} exec -i -n "${CNPG_NS}" "${CNPG_POD}" -- env PGPASSWORD="${SYNAPSE_PW}" \
    psql -U synapse_mrt0rtikize -d synapse_mrt0rtikize -h localhost < "${BACKUP_DIR}/dump-synapse.sql"
log "Synapse database restored."

log "Restoring MAS database..."
${K} exec -i -n "${CNPG_NS}" "${CNPG_POD}" -- env PGPASSWORD="${MAS_PW}" \
    psql -U mas_mrt0rtikize -d mas_mrt0rtikize -h localhost < "${BACKUP_DIR}/dump-mas.sql"
log "MAS database restored."

# -------------------------------------------------------------------
# Step 3: Apply generated secrets (CRITICAL)
# -------------------------------------------------------------------
log "=== Step 4: Applying generated secrets ==="

if [ -f "${BACKUP_DIR}/secret-generated.yaml" ]; then
    ${K} replace --force -f "${BACKUP_DIR}/secret-generated.yaml"
    log "Generated secret replaced: ${NS}-generated (original signing key from backup)"
else
    err "CRITICAL: secret-generated.yaml not found in backup!"
    err "SYNAPSE_SIGNING_KEY and MAS keys will NOT be restored."
    err "Federation identity is lost without this file."
fi

# -------------------------------------------------------------------
# Step 4: Apply deployment markers
# -------------------------------------------------------------------
log "=== Step 5: Applying deployment markers ==="

if [ -f "${BACKUP_DIR}/markers.yaml" ]; then
    ${K} replace --force -f "${BACKUP_DIR}/markers.yaml"
    log "Deployment markers replaced."
else
    warn "markers.yaml not found in backup (non-critical)."
fi

# -------------------------------------------------------------------
# Step 5: Scale Synapse to 1
# -------------------------------------------------------------------
log "=== Step 6: Starting Synapse ==="

${K} -n "${NS}" scale sts -l "app.kubernetes.io/component=matrix-server" --replicas=1 2>/dev/null || \
    ${K} -n "${NS}" scale sts "${NS}-synapse-main" --replicas=1 2>/dev/null

log "Waiting for Synapse to start..."
${K} -n "${NS}" wait --for=condition=ready pod -l "app.kubernetes.io/component=matrix-server" --timeout=300s 2>/dev/null || warn "Synapse is not ready yet, check logs."

# -------------------------------------------------------------------
# Step 6: Restore media files
# -------------------------------------------------------------------
log "=== Step 7: Restoring media files ==="

if [ -f "${BACKUP_DIR}/synapse-media.tar.gz" ]; then
    SYNAPSE_POD=$( ${K} -n "${NS}" get pods -l "app.kubernetes.io/component=matrix-server" -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}' 2>/dev/null)
    if [ -z "${SYNAPSE_POD}" ]; then
        warn "No running Synapse pod found for media restore. Skip media."
        warn "Re-run this step after Synapse is up:"
        warn "  kubectl cp synapse-media.tar.gz ${NS}/<synapse-pod>:/tmp/ && kubectl exec <synapse-pod> -- tar xzf /tmp/synapse-media.tar.gz -C /media/"
    else
        log "Copying media to Synapse pod: ${SYNAPSE_POD}"
        ${K} cp "${BACKUP_DIR}/synapse-media.tar.gz" "${NS}/${SYNAPSE_POD}:/tmp/synapse-media.tar.gz"
        ${K} exec -n "${NS}" "${SYNAPSE_POD}" -- tar xzf /tmp/synapse-media.tar.gz -C /media/
        ${K} exec -n "${NS}" "${SYNAPSE_POD}" -- rm /tmp/synapse-media.tar.gz
        log "Media files restored."
    fi
else
    warn "synapse-media.tar.gz not found in backup."
fi

# -------------------------------------------------------------------
# Step 7: Scale MAS to 1
# -------------------------------------------------------------------
log "=== Step 8: Starting MAS ==="

${K} -n "${NS}" scale deploy -l "app.kubernetes.io/component=matrix-authentication" --replicas=1 2>/dev/null || \
    ${K} -n "${NS}" scale deploy "${NS}-matrix-authentication-service" --replicas=1 2>/dev/null

log "Waiting for MAS to start..."
${K} -n "${NS}" wait --for=condition=ready pod -l "app.kubernetes.io/component=matrix-authentication" --timeout=120s 2>/dev/null || warn "MAS is not ready yet, check logs."

# -------------------------------------------------------------------
# Summary
# -------------------------------------------------------------------
cat <<SUMMARY

${GREEN}========================================${NC}
${GREEN}  Restore Complete: ${NS}${NC}
${GREEN}========================================${NC}

  ${YELLOW}Verification steps:${NC}
  1. Check Synapse logs:
     ${K} logs -n ${NS} -l "app.kubernetes.io/component=matrix-server" --tail=30
  2. Check Synapse has correct signing key:
     ${K} exec -n ${NS} deploy/${NS}-synapse-main -- ls /secrets/${NS}-generated/SYNAPSE_SIGNING_KEY
  3. Test login at: https://chat.mrt0rtikize.ru
  4. Federation tester: https://federationtester.matrix.org/?server_name=mrt0rtikize.ru
  5. Check certificates:
     ${K} get certificates -n ${NS}

SUMMARY
