#!/bin/bash
#
# billing-cache-warm.sh
#
# Pre-builds the monthly billing cache so /api/textInvoice serves instantly when
# billing is actually run later in the day. Scheduled for the 1st of each month at
# 4:00am Central (see `crontab -l`, guarded by CRON_TZ=America/Chicago).
#
# Bills the PREVIOUS calendar month (on Jun 1 it warms May 01..May 31), matching how
# billing has always been run on the 1st.
#
# The /api/textInvoice route scans every active store and takes ~2 min, so Cloudflare
# returns 524 at its ~120s edge timeout. That's expected and harmless: the route sets
# set_time_limit(0) + ignore_user_abort(true), so the origin finishes the build and
# writes the cache file after the edge has already given up. We therefore ignore the
# HTTP status and confirm success by polling for the cache file instead.
#
set -u
export TZ="America/Chicago"

LOG="/home/bkweb/logs/billing-cache-warm.log"
CACHE_DIR="/home/bkweb/output/billing"
ENDPOINT="https://buyerkiosk.com/api/textInvoice"

# Previous month's first and last day (computed in Central time).
START="$(date -d "$(date +%Y-%m-01) -1 month" +%Y-%m-01)"
END="$(date -d "$(date +%Y-%m-01) -1 day" +%Y-%m-%d)"

# Cache key must match the route: md5($startDate . '_' . $endDate).
HASH="$(printf '%s' "${START}_${END}" | md5sum | cut -d' ' -f1)"
CACHE_FILE="${CACHE_DIR}/${HASH}.json"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S %Z')] $*" >> "$LOG"; }

log "Warming billing cache for ${START}..${END} (hash ${HASH})"

# Idempotent: if the cache is already present, there is nothing to do.
if [ -f "$CACHE_FILE" ]; then
    log "Cache already present (${CACHE_FILE}, $(stat -c%s "$CACHE_FILE") bytes) — nothing to do."
    exit 0
fi

# Kick off the build in the background; the edge will 524 but the origin keeps going.
curl -s --max-time 300 -X POST "$ENDPOINT" \
     --data-urlencode "startDate=${START}" \
     --data-urlencode "endDate=${END}" \
     -o /dev/null -w "trigger HTTP %{http_code} after %{time_total}s" >> "$LOG" 2>&1 &
echo "" >> "$LOG"

# Poll up to 6 minutes for the origin to finish writing the cache file.
for _ in $(seq 1 72); do
    if [ -f "$CACHE_FILE" ]; then
        log "Cache built OK: ${CACHE_FILE} ($(stat -c%s "$CACHE_FILE") bytes)"
        exit 0
    fi
    sleep 5
done

log "ERROR: cache not built after ~6 min of polling: ${CACHE_FILE}"
exit 1
