#!/usr/bin/env bash
#
# Warm the order-form block_html category cache after a deploy / cache:flush.
#
# The re-order (SO) and forward-order (SF) forms are cacheable="false" pages, but
# their heavy work — building the ~76 per-category product grids — is cached in
# block_html for 24h, keyed on the dealer PROFILE (store x currency x tax-exempt x
# backorders), NOT the customer. So a cold profile costs ~6s (SO) / ~19s (SF) to
# render; warm it once and every dealer AND rep on that profile loads in ~0.1-0.5s.
#
# This script logs in as a Super Rep (who can act as any dealer) and, for ONE
# representative dealer per distinct profile, renders both forms over HTTP — which
# populates the shared cache. Run it right after each deploy/cache clear, and
# optionally on a schedule before the 24h lifetime expires.
#
# Usage:
#   REP_USER='rep@zhik.com' REP_PASS='...' ./bin/warm-order-forms.sh
#   BASE_URL='https://trade.zhik.com' REP_USER=... REP_PASS=... ./bin/warm-order-forms.sh
#
# Env:
#   BASE_URL   Site root (default https://trade.zhik.com). No trailing slash.
#   REP_USER   Super Rep login email (required).
#   REP_PASS   Super Rep password (required).
#   MAX_TIME   Per-request timeout in seconds (default 60 — a cold SF is ~19s + RTT).
#
# Representative dealer ids: one per profile that has at least one dealer logged in
# within the last ~7 days (dead profiles are skipped — no active dealer hits them).
# Each id is the MOST RECENTLY active dealer on its profile, so we warm real,
# in-use profiles via a real account. Generated from the customer base; entity ids
# can differ between environments (though this DB is a recent prod copy), so
# regenerate on the target with the "active representative" SQL in
# _plans/order-form-load-optimization/README.md, or pass WARM_DEALER_IDS='...'.

set -uo pipefail

BASE_URL="${BASE_URL:-https://trade.zhik.com}"
BASE_URL="${BASE_URL%/}"
REP_USER="${REP_USER:?set REP_USER to a Super Rep email}"
REP_PASS="${REP_PASS:?set REP_PASS to the Super Rep password}"
MAX_TIME="${MAX_TIME:-60}"

# One representative dealer id per distinct profile (26 profiles cover 100% of
# dealers). See header note on regenerating for prod.
# 11 active profiles (dealers logged in within ~7 days), most-active rep each:
#   8469 EUR/g8  8263 AUD/g4  1649 USD/g8  1510 GBP/g8  32422 EUR/g4  1673 AUD/g8
#   37290 NZD/g4  30800 USD/g4  12594 NZD/g8  30903 EUR/g8(store4)  18163 USD/g9
DEALER_IDS=(
  8469 8263 1649 1510 32422 1673 37290 30800 12594 30903 18163
)

# Override the id list without editing this file (space-separated), e.g. to warm a
# subset or point at a different environment's ids: WARM_DEALER_IDS='1429 1400'.
if [ -n "${WARM_DEALER_IDS:-}" ]; then
  read -ra DEALER_IDS <<< "$WARM_DEALER_IDS"
fi

command -v curl >/dev/null 2>&1 || { echo "curl is required" >&2; exit 1; }

COOKIE_JAR="$(mktemp)"
trap 'rm -f "$COOKIE_JAR"' EXIT

cj() { curl -sS -c "$COOKIE_JAR" -b "$COOKIE_JAR" --max-time "$MAX_TIME" "$@"; }

# The form_key COOKIE is set client-side by JS, so curl never has it; read the
# value out of a rendered form's hidden <input name="form_key" value="..."> instead.
extract_form_key() {
  grep -o 'name="form_key"[^>]*value="[^"]*"' | sed -E 's/.*value="([^"]*)".*/\1/' | head -1
}

echo "==> Warming order forms on $BASE_URL"

# --- Log in as the Super Rep -------------------------------------------------
FK="$(cj "$BASE_URL/customer/account/login/" | extract_form_key)"
[ -n "$FK" ] || { echo "!! Could not read a form_key from the login page." >&2; exit 1; }
cj -X POST "$BASE_URL/customer/account/loginPost/" \
   --data-urlencode "login[username]=$REP_USER" \
   --data-urlencode "login[password]=$REP_PASS" \
   --data-urlencode "form_key=$FK" -o /dev/null

# Verify login and grab the post-login form_key (the account edit form always has
# one) for the setdealer POSTs. Follow redirects so a bounce to login is caught.
EDIT_HTML="$(cj -L "$BASE_URL/customer/account/edit/")"
if ! printf '%s' "$EDIT_HTML" | grep -q 'customer/account/logout'; then
  echo "!! Login failed for $REP_USER — check REP_USER / REP_PASS." >&2
  exit 1
fi
FK="$(printf '%s' "$EDIT_HTML" | extract_form_key)"
[ -n "$FK" ] || { echo "!! Could not read the post-login form_key." >&2; exit 1; }
echo "    logged in as $REP_USER"

# --- Warm each profile -------------------------------------------------------
total=${#DEALER_IDS[@]}
n=0
ok=0
start=$SECONDS

for id in "${DEALER_IDS[@]}"; do
  n=$((n + 1))

  # Act as this dealer (needed for the inline forward-order render).
  cj -X POST "$BASE_URL/portal/salesrep/setdealer/" \
     -H "X-Requested-With: XMLHttpRequest" \
     --data-urlencode "customerid=$id" \
     --data-urlencode "form_key=$FK" -o /dev/null

  # SO re-order: dealerorder renders the supergrid for the given dealer.
  so=$(cj -H "X-Requested-With: XMLHttpRequest" \
        "$BASE_URL/portal/salesrep/dealerorder/?customerid=$id" \
        -o /dev/null -w '%{http_code} %{time_total}s' || echo 'ERR -')

  # SF forward-order: rendered inline for the acting dealer.
  fo=$(cj "$BASE_URL/forward-order/order/" \
        -o /dev/null -w '%{http_code} %{time_total}s' || echo 'ERR -')

  printf '    [%2d/%2d] dealer %-6s  SO %-14s  FO %-14s\n' "$n" "$total" "$id" "$so" "$fo"

  case "$so $fo" in
    200\ *200\ *) ok=$((ok + 1)) ;;
  esac
done

echo "==> Done: $ok/$total profiles warmed in $((SECONDS - start))s"
[ "$ok" -eq "$total" ] || echo "   (some profiles did not return 200 — see rows above)"
