#!/bin/bash
set -Eeuo pipefail

# Configuration
TARGET_ENV="${1:-stsharedservices-dev}"
DBNAME="${2:-geco}"
POD_NAME="${3:-stpgclusterdev-1}"
CONTAINER_NAME="${4:-postgres}"
BACKUP_FILE="${5:-.}"
DROP_IF_EXISTS="${6:-true}"
DB_USER="${7:-${PGUSER:-postgres}}"
DB_PASSWORD="${8:-${PGPASSWORD:-}}"

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

# Logging functions
log() {
  echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $*"
}

error() {
  echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $*" >&2
  exit 1
}

warn() {
  echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARN:${NC} $*"
}

info() {
  echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $*"
}

log "Inizio restore database PostgreSQL"
log "Namespace target: ${TARGET_ENV}"
log "Pod target: ${POD_NAME}"
log "Database: ${DBNAME}"
log "DB user: ${DB_USER}"
log "File backup: ${BACKUP_FILE}"

# Validate backup file exists
if [ ! -f "${BACKUP_FILE}" ]; then
  error "File di backup non trovato: ${BACKUP_FILE}"
fi

FILE_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
log "Dimensione file backup: ${FILE_SIZE}"

# Determine if backup is compressed
if [[ "${BACKUP_FILE}" == *.gz ]]; then
  IS_COMPRESSED=true
  info "Backup compresso (gzip) rilevato"
else
  IS_COMPRESSED=false
  info "Backup non compresso rilevato"
fi

# Check if namespace exists
if ! kubectl get namespace "${TARGET_ENV}" &>/dev/null; then
  error "Namespace '${TARGET_ENV}' non trovato"
fi

# Check if pod exists
if ! kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" &>/dev/null; then
  error "Pod '${POD_NAME}' non trovato nel namespace '${TARGET_ENV}'"
fi

# Check if pod is running
POD_STATUS=$(kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" -o jsonpath='{.status.phase}')
if [ "${POD_STATUS}" != "Running" ]; then
  error "Pod '${POD_NAME}' non è in stato Running (stato attuale: ${POD_STATUS})"
fi

# Check database connectivity
info "Verifica connessione al database..."
if ! kubectl exec -i "${POD_NAME}" \
  -c "${CONTAINER_NAME}" \
  -n "${TARGET_ENV}" \
  -- env "PGPASSWORD=${DB_PASSWORD}" pg_isready -U "${DB_USER}" -d "${DBNAME}" &>/dev/null; then
  error "Impossibile connettersi a PostgreSQL nel pod '${POD_NAME}'"
fi

log "Connessione al database verificata"

# Drop database if requested
if [ "${DROP_IF_EXISTS}" = "true" ]; then
  warn "Elimino il database '${DBNAME}' se esiste..."
  kubectl exec -i "${POD_NAME}" \
    -c "${CONTAINER_NAME}" \
    -n "${TARGET_ENV}" \
    -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "DROP DATABASE IF EXISTS \"${DBNAME}\" WITH (FORCE);" 2>/dev/null || warn "Database non esiste o elimina non è riuscita"
  
  info "Creo nuovo database '${DBNAME}'..."
  kubectl exec -i "${POD_NAME}" \
    -c "${CONTAINER_NAME}" \
    -n "${TARGET_ENV}" \
    -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "CREATE DATABASE \"${DBNAME}\";" || error "Impossibile creare il database '${DBNAME}'"
fi

log "Inizio restore del database..."

# Execute restore
if [ "${IS_COMPRESSED}" = "true" ]; then
  info "Decompressione e restore in corso..."
  gunzip -c "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
    -c "${CONTAINER_NAME}" \
    -n "${TARGET_ENV}" \
    -- env "PGPASSWORD=${DB_PASSWORD}" pg_restore -U "${DB_USER}" -d "${DBNAME}" --no-owner -v 2>&1 | grep -E "(NOTICE|ERROR|completed)" || true
else
  info "Restore da file plain SQL in corso..."
  cat "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
    -c "${CONTAINER_NAME}" \
    -n "${TARGET_ENV}" \
    -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 2>&1 | grep -E "(NOTICE|ERROR|INSERT|CREATE)" | tail -20 || true
fi

log "Restore completato"

info "Allineo owner delle tabelle al proprietario del database target..."
TARGET_DB_OWNER=$(kubectl exec -i "${POD_NAME}" \
  -c "${CONTAINER_NAME}" \
  -n "${TARGET_ENV}" \
  -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d postgres -t -A -c "SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname='${DBNAME}';")

if [ -z "${TARGET_DB_OWNER}" ]; then
  error "Impossibile determinare l'owner del database '${DBNAME}'"
fi

kubectl exec -i "${POD_NAME}" \
  -c "${CONTAINER_NAME}" \
  -n "${TARGET_ENV}" \
  -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 -c "DO \$\$ DECLARE r RECORD; BEGIN FOR r IN SELECT n.nspname, c.relname FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'p') AND n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_toast%' LOOP EXECUTE format('ALTER TABLE %I.%I OWNER TO %I', r.nspname, r.relname, '${TARGET_DB_OWNER}'); END LOOP; END \$\$;" >/dev/null

log "Owner tabelle allineato a '${TARGET_DB_OWNER}'"

# Verify restore success
info "Verifica integrità database..."
TABLE_COUNT=$(kubectl exec -i "${POD_NAME}" \
  -c "${CONTAINER_NAME}" \
  -n "${TARGET_ENV}" \
  -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='public';" 2>/dev/null || echo "0")

if [ "${TABLE_COUNT}" -gt 0 ]; then
  log "✅ Restore completato con successo"
  log "Database '${DBNAME}' contiene ${TABLE_COUNT} tabelle"
else
  warn "⚠️  Database '${DBNAME}' non contiene tabelle pubbliche (potrebbe essere empty)"
fi

# Get database size
DB_SIZE=$(kubectl exec -i "${POD_NAME}" \
  -c "${CONTAINER_NAME}" \
  -n "${TARGET_ENV}" \
  -- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -t -c "SELECT pg_size_pretty(pg_database_size('${DBNAME}'));" 2>/dev/null || echo "N/A")

log "Dimensione database: ${DB_SIZE}"
log "✅ Restore completato con successo"
