#!/usr/bin/env bash
#
# install-backup-cron.sh
# -----------------------
# One-shot installer for the Africa Alert SQLite backup cron job.
#
# Idempotent: re-running is a no-op if the cron entry is already present
# (detected by `crontab -l | grep -q africa-alert`).
#
# Default schedule: every 12 hours (00:00 and 12:00 UTC).
# Override with CRON_SCHEDULE env var, e.g.
#   CRON_SCHEDULE="0 */6 * * *" sudo ./install-backup-cron.sh
#
# This script is meant to be run on the production Ubuntu 22.04 host.
# It is NOT a Windows script. On a Windows dev box, only
# `bash -n install-backup-cron.sh` (syntax check) is meaningful.

set -eu

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"

BACKUP_SCRIPT="${SCRIPT_DIR}/africa-alert-backup.sh"
CRON_SCHEDULE="${CRON_SCHEDULE:-0 */12 * * *}"   # every 12h, on the hour
LOG_DIR="${LOG_DIR:-${PROJECT_ROOT}/logs}"
INSTALL_LOG="${LOG_DIR}/backup-install.log"

# Marker used by both the grep-based idempotency check and as a comment
# inside the crontab so an operator reading `crontab -l` knows what the
# line does. Keep the marker stable — other tooling relies on it.
CRON_MARKER="africa-alert-backup"

mkdir -p "${LOG_DIR}"
touch "${INSTALL_LOG}"

log() {
  local msg="[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [install-cron] $*"
  echo "${msg}" | tee -a "${INSTALL_LOG}" >&2
}

if [ ! -x "${BACKUP_SCRIPT}" ]; then
  log "ERROR: backup script not found or not executable: ${BACKUP_SCRIPT}"
  log "Hint: chmod +x ${BACKUP_SCRIPT}"
  exit 1
fi

# Idempotency check: does the current crontab already contain our marker?
if command -v crontab >/dev/null 2>&1; then
  EXISTING="$(crontab -l 2>/dev/null || true)"
  if echo "${EXISTING}" | grep -q "${CRON_MARKER}"; then
    log "cron entry already installed; nothing to do."
    log "current crontab:"
    echo "${EXISTING}" | grep "${CRON_MARKER}" | sed 's/^/    /' | tee -a "${INSTALL_LOG}" >&2
    log "to reinstall, first run: crontab -l | grep -v '${CRON_MARKER}' | crontab -"
    exit 0
  fi
else
  log "WARN: crontab command not found; this is not a Linux host. Aborting."
  exit 1
fi

# Build the cron line. The marker is a leading comment so it's greppable.
CRON_LINE="${CRON_SCHEDULE} /bin/bash ${BACKUP_SCRIPT} >> ${LOG_DIR}/backup.log 2>&1 # ${CRON_MARKER}"

# Install: append the new line to whatever crontab exists, or create one
# if none. `crontab -` reads from stdin.
{
  echo "${EXISTING:-}"
  echo "${CRON_LINE}"
} | crontab -

# Compute the next-run time. We use a small GNU-date trick: if now is
# earlier than the next scheduled firing, that's the next run; otherwise
# advance by 12h. This is a best-effort estimate — cron itself is the
# source of truth. Format: YYYY-MM-DD HH:MM:SS UTC.
compute_next_run() {
  local now_epoch
  now_epoch="$(date -u +%s)"
  # Step forward in 12h blocks until we land in the future.
  local candidate="${now_epoch}"
  while [ "${candidate}" -le "${now_epoch}" ]; do
    candidate=$((candidate + 12 * 3600))
  done
  # Snap to the next "round" 12h boundary (00:00 or 12:00 UTC) by
  # subtracting (epoch mod 12h). This matches CRON_SCHEDULE default.
  local bucket=$((candidate % (12 * 3600)))
  candidate=$((candidate - bucket))
  # If snapping pushed us into the past, add another 12h.
  if [ "${candidate}" -le "${now_epoch}" ]; then
    candidate=$((candidate + 12 * 3600))
  fi
  date -u -d "@${candidate}" +"%Y-%m-%d %H:%M:%S UTC"
}

NEXT_RUN="$(compute_next_run)"

log "installed cron entry:"
log "    ${CRON_LINE}"
log "next scheduled run (estimate): ${NEXT_RUN}"
log "verify with: crontab -l | grep ${CRON_MARKER}"
log "uninstall with: crontab -l | grep -v '${CRON_MARKER}' | crontab -"

exit 0
