#!/usr/bin/env bash
#
# HTTP integration matrix for POST /demo-request (Navagoo API).
# Exercises the full running stack: routing → CORS → origin allow-list →
# API key → honeypot → validation → SMTP send.
#
# Usage:
#   API_BASE=http://api.navagoo.localhost \
#   DEMO_KEY=<DEMO_FORM_API_KEY> \
#   ORIGIN=https://www.navagoo.com \
#   bash tests/demo-form/http_integration.sh
#
# Defaults target the local dev stack. Exit code 0 = all passed.

set -uo pipefail

API_BASE="${API_BASE:-http://api.navagoo.localhost}"
ENDPOINT="$API_BASE/demo-request"
KEY="${DEMO_KEY:-8b60d22cd180d650bc3717bd9c5a1c5fc9d2a42fb1dd1e01d87cfbaefd1a8e5d}"
ORIGIN="${ORIGIN:-https://www.navagoo.com}"

PASS=0; FAIL=0
green(){ printf '\033[32m%s\033[0m' "$1"; }
red(){ printf '\033[31m%s\033[0m' "$1"; }

# assert_status <expected> <label> <curl-args...>
# Deterministic assertion for the non-SMTP paths (fast, no retry).
assert_status(){
  local expected="$1" label="$2"; shift 2
  local code
  code=$(curl -sS -m 50 -o /dev/null -w '%{http_code}' "$@" 2>/dev/null)
  if [ "$code" = "$expected" ]; then
    PASS=$((PASS+1)); printf '  %s  %s (HTTP %s)\n' "$(green PASS)" "$label" "$code"
  else
    FAIL=$((FAIL+1)); printf '  %s  %s (expected %s, got %s)\n' "$(red FAIL)" "$label" "$expected" "$code"
  fi
}

# assert_email <expected> <label> <curl-args...>
# Happy paths actually send over SMTP. The dev Mailtrap sandbox throttles
# rapid-fire sends, so retry transient failures (timeouts, 5xx) at the curl
# layer to keep the assertion about endpoint behaviour, not SMTP weather.
assert_email(){
  local expected="$1" label="$2"; shift 2
  local code
  code=$(curl -sS -m 50 --retry 4 --retry-delay 5 --retry-all-errors \
              -o /dev/null -w '%{http_code}' "$@" 2>/dev/null)
  if [ "$code" = "$expected" ]; then
    PASS=$((PASS+1)); printf '  %s  %s (HTTP %s)\n' "$(green PASS)" "$label" "$code"
  else
    FAIL=$((FAIL+1)); printf '  %s  %s (expected %s, got %s — SMTP sandbox may be throttling)\n' "$(red FAIL)" "$label" "$expected" "$code"
  fi
}

# assert_header_absent <header-regex> <label> <curl-args...>
assert_header_absent(){
  local hdr="$1" label="$2"; shift 2
  if curl -sS -m 50 -D - -o /dev/null "$@" 2>/dev/null | grep -iq "$hdr"; then
    FAIL=$((FAIL+1)); printf '  %s  %s (header %s unexpectedly present)\n' "$(red FAIL)" "$label" "$hdr"
  else
    PASS=$((PASS+1)); printf '  %s  %s\n' "$(green PASS)" "$label"
  fi
}

CT='Content-Type: application/json'
AC='Accept: application/json'
VALID='{"name":"Sara Ali","business":"Glow Salon","phone":"+966500000000","email":"sara@example.com","city":"Riyadh","message":"Please show me a demo."}'

echo
echo "Target: $ENDPOINT   Origin: $ORIGIN"
echo "──────────────────────────────────────────────"
echo "Functional (happy paths — these send email over SMTP; transient retries on):"
assert_email 200 "valid submission"          -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d "$VALID"
assert_email 200 "required fields only"       -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"A B","business":"Biz","phone":"0500000000","email":"a@b.com"}'
assert_email 200 "unicode / Arabic content"   -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"سارة","business":"صالون","phone":"0500000000","email":"ar@example.sa","city":"الرياض","message":"أرغب بعرض"}'
assert_email 200 "XSS payload accepted (encoded server-side)" -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"<script>alert(1)</script>","business":"</td><img src=x onerror=alert(1)>","phone":"0500000000","email":"xss@example.com","message":"\"><b>hi</b>"}'
assert_email 200 "origin via Referer fallback" -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Referer: $ORIGIN/partners" -H "X-Api-Key: $KEY" -d "$VALID"

echo
echo "API key gate:"
assert_status 401 "missing X-Api-Key"           -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -d "$VALID"
assert_status 401 "wrong X-Api-Key"             -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: deadbeef" -d "$VALID"
assert_status 401 "empty X-Api-Key value"        -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key;" -d "$VALID"

echo
echo "Origin allow-list (server-side):"
assert_status 403 "disallowed Origin"            -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: https://evil.example.com" -H "X-Api-Key: $KEY" -d "$VALID"
assert_status 403 "no Origin / no Referer"        -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "X-Api-Key: $KEY" -d "$VALID"
assert_status 403 "spoofed Referer host"          -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Referer: https://evil.example.com/x" -H "X-Api-Key: $KEY" -d "$VALID"

echo
echo "Honeypot (bot ⇒ looks OK, silently dropped, no email):"
assert_status 200 "filled botcheck ⇒ 200"        -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"Bot","business":"X","phone":"0500000000","email":"bot@x.com","botcheck":"1"}'

echo
echo "Input validation:"
assert_status 422 "missing required fields"       -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"","business":"","phone":"","email":""}'
assert_status 422 "invalid email"                  -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"A","business":"B","phone":"0500000000","email":"not-an-email"}'
assert_status 422 "invalid phone (letters)"        -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"A","business":"B","phone":"call-me","email":"a@b.com"}'
assert_status 422 "oversized name (>150)"          -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d "{\"name\":\"$(printf 'a%.0s' {1..151})\",\"business\":\"B\",\"phone\":\"0500000000\",\"email\":\"a@b.com\"}"
assert_status 422 "empty JSON object"              -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{}'

echo
echo "Protocol / method abuse:"
assert_status 400 "malformed JSON body"            -X POST "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d '{"name":"A", oops'
assert_status 405 "GET not allowed"                -X GET  "$ENDPOINT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY"
assert_status 405 "PUT not allowed"                -X PUT  "$ENDPOINT" -H "$CT" -H "$AC" -H "Origin: $ORIGIN" -H "X-Api-Key: $KEY" -d "$VALID"

echo
echo "CORS preflight:"
assert_status 200 "OPTIONS preflight ⇒ 200"        -X OPTIONS "$ENDPOINT" -H "Origin: $ORIGIN" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: content-type,x-api-key"
assert_header_absent 'access-control-allow-origin' "no CORS header for disallowed origin" \
  -X OPTIONS "$ENDPOINT" -H "Origin: https://evil.example.com" -H "Access-Control-Request-Method: POST"

echo "──────────────────────────────────────────────"
if [ "$FAIL" -eq 0 ]; then printf '%s\n' "$(green "$PASS passed, $FAIL failed")"; else printf '%s\n' "$(red "$PASS passed, $FAIL failed")"; fi
echo "Note: per-IP rate limit (429) is not exercised here — dev uses DummyCache (no-op)."
echo "      Verify throttling in staging/prod where FileCache is active."
exit $([ "$FAIL" -eq 0 ] && echo 0 || echo 1)
