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

# Fetch SPAPS production database dump via SSH (read-only on production).
# Output: ${SPAPS_CACHE_ROOT:-~/.cache/spaps}/db/prod.sql.gz
#
# Environment variables:
#   SPAPS_PROD_DB_FRESH=1         Force re-fetch even if a cached dump exists
#   SPAPS_CACHE_ROOT              Override cache directory
#   SPAPS_PROD_HOST               Primary SSH host
#   SPAPS_PROD_HOST_FALLBACK      Fallback SSH host
#   SPAPS_SSH_BIN                 SSH binary path

PRIMARY_PROD_HOST="${SPAPS_PROD_HOST:-aiops@sweet-potato-prod}"
FALLBACK_PROD_HOST="${SPAPS_PROD_HOST_FALLBACK:-root@104.131.188.214}"
PROD_HOST=""
SSH_BIN="${SPAPS_SSH_BIN:-ssh}"
CACHE_DIR="${SPAPS_CACHE_ROOT:-${HOME}/.cache/spaps}/db"
PROD_DUMP="${CACHE_DIR}/prod.sql.gz"
FRESH="${SPAPS_PROD_DB_FRESH:-0}"

info() {
  printf '\n%s %s\n' "🔧" "$1"
}

err() {
  printf '\n%s %s\n' "❌" "$1" >&2
}

file_mtime_epoch() {
  local path="$1"
  local mtime

  # Probe GNU coreutils first (`stat -c %Y`), then BSD/macOS (`stat -f %m`).
  # The two flag dialects are mutually incompatible: `stat -f` on GNU means
  # "file system status" and prints multi-line garbage, so we must validate
  # that we captured a bare epoch integer before trusting it.
  if mtime=$(stat -c %Y "${path}" 2>/dev/null) && [[ "${mtime}" =~ ^[0-9]+$ ]]; then
    printf '%s\n' "${mtime}"
    return 0
  fi

  if mtime=$(stat -f %m "${path}" 2>/dev/null) && [[ "${mtime}" =~ ^[0-9]+$ ]]; then
    printf '%s\n' "${mtime}"
    return 0
  fi

  return 1
}

resolve_prod_host() {
  local candidate
  local candidates=("${PRIMARY_PROD_HOST}")
  if [[ -n "${FALLBACK_PROD_HOST}" && "${FALLBACK_PROD_HOST}" != "${PRIMARY_PROD_HOST}" ]]; then
    candidates+=("${FALLBACK_PROD_HOST}")
  fi

  for candidate in "${candidates[@]}"; do
    info "Testing SSH connection to ${candidate}..."
    if "${SSH_BIN}" -o ConnectTimeout=5 -o BatchMode=yes "${candidate}" "echo ok" >/dev/null 2>&1; then
      PROD_HOST="${candidate}"
      return 0
    fi
  done

  return 1
}

if [[ -f "${PROD_DUMP}" ]]; then
  case "${FRESH}" in
    1|true|TRUE|yes|YES)
      info "SPAPS_PROD_DB_FRESH=1 set, fetching fresh dump from production..."
      ;;
    *)
      if DUMP_MTIME="$(file_mtime_epoch "${PROD_DUMP}")"; then
        DUMP_AGE=$(( $(date +%s) - DUMP_MTIME ))
        DUMP_AGE_HOURS=$(( DUMP_AGE / 3600 ))
        info "Using cached prod dump (${DUMP_AGE_HOURS}h old): ${PROD_DUMP}"
      else
        info "Using cached prod dump: ${PROD_DUMP}"
      fi
      info "Run with SPAPS_PROD_DB_FRESH=1 to fetch fresh data."
      exit 0
      ;;
  esac
fi

mkdir -p "${CACHE_DIR}"

if ! command -v "${SSH_BIN}" >/dev/null 2>&1; then
  err "ssh command not found: ${SSH_BIN}"
  exit 1
fi

if ! resolve_prod_host; then
  err "Cannot connect to any configured production host."
  err "Tried: ${PRIMARY_PROD_HOST} ${FALLBACK_PROD_HOST}"
  err "Check your SSH key is loaded: ssh-add -l"
  err "Try manually: ssh ${PRIMARY_PROD_HOST}"
  exit 1
fi
info "Using production SSH host: ${PROD_HOST}"

info "Fetching SPAPS production database dump via SSH (read-only)..."
info "This may take a minute..."

set +e
"${SSH_BIN}" "${PROD_HOST}" "docker exec spaps-python-db pg_dump -U spaps spaps" 2>"${PROD_DUMP}.err" | gzip > "${PROD_DUMP}.tmp"
pipe_status=("${PIPESTATUS[@]}")
set -e
ssh_status=${pipe_status[0]:-1}
gzip_status=${pipe_status[1]:-1}

if [[ $ssh_status -ne 0 || $gzip_status -ne 0 ]]; then
  err "Failed to dump production database (ssh exit ${ssh_status}, gzip exit ${gzip_status})"
  if [[ $gzip_status -ne 0 ]]; then
    err "Local compression/write failed (check disk space and file permissions)."
  fi
  if [[ -s "${PROD_DUMP}.err" ]]; then
    err "Error output:"
    cat "${PROD_DUMP}.err" >&2
  fi
  rm -f "${PROD_DUMP}.tmp" "${PROD_DUMP}.err"
  exit 1
fi
rm -f "${PROD_DUMP}.err"

if [[ ! -s "${PROD_DUMP}.tmp" ]]; then
  err "Dump file is empty"
  rm -f "${PROD_DUMP}.tmp"
  exit 1
fi

mv "${PROD_DUMP}.tmp" "${PROD_DUMP}"

DUMP_SIZE=$(du -h "${PROD_DUMP}" | cut -f1)
info "Production dump saved: ${PROD_DUMP} (${DUMP_SIZE})"
