#!/usr/bin/env bash
# scripts/restore.sh — Database restore helper for Orion and Gitea
#
# Usage:
#   bash scripts/restore.sh orion ~/backups/orion/daily/orion_20260214_030000.sql.gz
#   bash scripts/restore.sh gitea ~/backups/gitea/daily/gitea_20260214_030000.sql.gz
#
# What it does:
#   1. Stops app containers (keeps DB running)
#   2. Drops and recreates the database
#   3. Restores from the .sql.gz backup
#   4. Runs Alembic migrations (Orion only)
#   5. Restarts all containers

set -euo pipefail

# =============================================================================
# Configuration
# =============================================================================
ORION_APP_DIR="${HOME}/apps/orion"

# =============================================================================
# Functions
# =============================================================================
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

usage() {
    echo "Usage: $0 <target> <backup-file>"
    echo ""
    echo "  target:      'orion' or 'gitea'"
    echo "  backup-file: path to .sql.gz file"
    echo ""
    echo "Examples:"
    echo "  $0 orion ~/backups/orion/daily/orion_20260214_030000.sql.gz"
    echo "  $0 gitea ~/backups/gitea/daily/gitea_20260214_030000.sql.gz"
    exit 1
}

restore_orion() {
    local backup_file="$1"
    local container="orion-db-1"
    local db_name="orion_db"
    local db_user="orion_user"

    log "=== Restoring Orion database ==="

    # Stop app containers (keep DB and Redis running)
    log "Stopping Orion app containers..."
    cd "${ORION_APP_DIR}"
    docker compose --profile full stop api celery-worker celery-beat flower redis-exporter 2>/dev/null || true

    # Drop and recreate database
    log "Dropping and recreating ${db_name}..."
    docker exec "${container}" psql -U "${db_user}" -d postgres -c \
        "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${db_name}' AND pid <> pg_backend_pid();" 2>/dev/null || true
    docker exec "${container}" dropdb -U "${db_user}" --if-exists "${db_name}"
    docker exec "${container}" createdb -U "${db_user}" "${db_name}"

    # Restore
    log "Restoring from ${backup_file}..."
    gunzip -c "${backup_file}" | docker exec -i "${container}" psql -U "${db_user}" -d "${db_name}" --quiet

    # Run migrations
    log "Running Alembic migrations..."
    docker compose --profile full start api 2>/dev/null || \
        docker compose --profile full up -d api

    # Wait for API container to be healthy before running migrations
    log "Waiting for API container to be ready..."
    for i in $(seq 1 12); do
        if docker compose --profile full exec -T db pg_isready -U orion_user -d orion_db > /dev/null 2>&1; then
            log "Database is ready (attempt $i/12)"
            break
        fi
        [ "$i" -eq 12 ] && { log "WARNING: database may not be ready, attempting migration anyway"; }
        sleep 5
    done

    docker compose --profile full exec -T -e PYTHONPATH=/app api python -m alembic upgrade heads

    # Restart all
    log "Restarting all services..."
    docker compose --profile full up -d

    log "=== Orion restore complete ==="
}

restore_gitea() {
    local backup_file="$1"
    local container="gitea-db"
    local db_name="gitea"
    local db_user="gitea"
    local gitea_dir="${HOME}/gitea"

    log "=== Restoring Gitea database ==="

    # Stop Gitea container (keep DB running)
    log "Stopping Gitea..."
    cd "${gitea_dir}"
    docker compose stop gitea 2>/dev/null || true

    # Drop and recreate database
    log "Dropping and recreating ${db_name}..."
    docker exec "${container}" psql -U "${db_user}" -d postgres -c \
        "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${db_name}' AND pid <> pg_backend_pid();" 2>/dev/null || true
    docker exec "${container}" dropdb -U "${db_user}" --if-exists "${db_name}"
    docker exec "${container}" createdb -U "${db_user}" "${db_name}"

    # Restore
    log "Restoring from ${backup_file}..."
    gunzip -c "${backup_file}" | docker exec -i "${container}" psql -U "${db_user}" -d "${db_name}" --quiet

    # Restart Gitea
    log "Restarting Gitea..."
    docker compose up -d

    log "=== Gitea restore complete ==="
}

# =============================================================================
# Main
# =============================================================================
if [ $# -lt 2 ]; then
    usage
fi

TARGET="$1"
BACKUP_FILE="$2"

# Validate backup file
if [ ! -f "${BACKUP_FILE}" ]; then
    log "ERROR: Backup file not found: ${BACKUP_FILE}"
    exit 1
fi

if [[ ! "${BACKUP_FILE}" == *.sql.gz ]]; then
    log "ERROR: Expected a .sql.gz file, got: ${BACKUP_FILE}"
    exit 1
fi

# Confirm
log "WARNING: This will DROP and RECREATE the ${TARGET} database!"
log "Backup file: ${BACKUP_FILE}"
read -rp "Continue? (y/N) " confirm
if [[ "${confirm}" != [yY] ]]; then
    log "Aborted."
    exit 0
fi

case "${TARGET}" in
    orion)
        restore_orion "${BACKUP_FILE}"
        ;;
    gitea)
        restore_gitea "${BACKUP_FILE}"
        ;;
    *)
        log "ERROR: Unknown target '${TARGET}'. Use 'orion' or 'gitea'."
        usage
        ;;
esac
