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

BASE_URL="${BASE_URL:-http://127.0.0.1:8080}"
DB_PATH="${DB_PATH:-fixture/fixture.db}"
RUN_ID="${RUN_ID:-$(date +%s)}"

echo "[security-smoke] checking service readiness"
curl -fsS -H 'X-WP-User: admin' "$BASE_URL/wp-json/calendar/v1/events" >/dev/null

echo "[security-smoke] checking register token non-disclosure"
register_email="sec-nodisclose-${RUN_ID}@example.test"
reg_code="$(curl -sS -o /tmp/sec_register.json -w '%{http_code}' -H 'Content-Type: application/json' \
  -d "{\"email\":\"${register_email}\",\"password\":\"strongpass123\"}" \
  "$BASE_URL/wp-json/calendar/v1/users/register")"
if [ "$reg_code" != "200" ] && [ "$reg_code" != "201" ] && [ "$reg_code" != "409" ]; then
  echo "[security-smoke] FAIL: unexpected register status $reg_code"
  exit 1
fi
reg_payload="$(cat /tmp/sec_register.json)"
if echo "$reg_payload" | grep -q 'verification_token_fixture'; then
  echo "[security-smoke] FAIL: register response leaked verification token"
  exit 1
fi

echo "[security-smoke] checking forgot-password token non-disclosure"
forgot_payload="$(curl -fsS -H 'Content-Type: application/json' \
  -d '{"email":"adrians@chezstephens.org.uk"}' \
  "$BASE_URL/wp-json/calendar/v1/users/forgot-password")"
if echo "$forgot_payload" | grep -q 'reset_token_fixture'; then
  echo "[security-smoke] FAIL: forgot-password response leaked reset token"
  exit 1
fi

echo "[security-smoke] checking register rate limiting"
seen_429=0
rate_prefix="sec-rate-${RUN_ID}"
for i in $(seq 1 10); do
  code="$(curl -sS -o /tmp/sec_reg_$i.json -w '%{http_code}' \
    -H 'Content-Type: application/json' \
    -d "{\"email\":\"${rate_prefix}-$i@example.test\",\"password\":\"strongpass123\"}" \
    "$BASE_URL/wp-json/calendar/v1/users/register")"
  if [ "$code" = "429" ]; then
    seen_429=1
    break
  fi
done
if [ "$seen_429" -ne 1 ]; then
  echo "[security-smoke] FAIL: expected 429 from register rate limiter"
  exit 1
fi

echo "[security-smoke] checking password hash format in database"
python3 - "$DB_PATH" <<'PY'
import sqlite3
import sys

db_path = sys.argv[1]
conn = sqlite3.connect(db_path)
cur = conn.cursor()
rows = cur.execute("SELECT email, password_hash FROM caldav_users").fetchall()
conn.close()
if not rows:
    print("[security-smoke] FAIL: no users found")
    raise SystemExit(1)
for email, pw_hash in rows:
    if not isinstance(pw_hash, str) or not pw_hash.startswith("pbkdf2_sha256$"):
        print(f"[security-smoke] FAIL: non-pbkdf2 hash for {email}: {pw_hash!r}")
        raise SystemExit(1)
print("[security-smoke] password hash format OK")
PY

echo "[security-smoke] checking strict CalDAV resource filename semantics"
resource="sec-$(date +%s).ics"
cat > /tmp/sec_caldav.ics <<'ICS'
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Security Smoke//EN
BEGIN:VEVENT
UID:sec-smoke-uid@example.test
SUMMARY:Security Smoke Event
DTSTART:20260415T100000
DTEND:20260415T110000
END:VEVENT
END:VCALENDAR
ICS
put_code="$(curl -sS -o /tmp/sec_caldav_put.json -w '%{http_code}' \
  -u adrians@chezstephens.org.uk:brillig1 \
  -X PUT --data-binary @/tmp/sec_caldav.ics \
  "$BASE_URL/caldav/calendars/public/$resource")"
if [ "$put_code" != "201" ] && [ "$put_code" != "200" ]; then
  echo "[security-smoke] FAIL: expected 200/201 for CalDAV PUT, got $put_code"
  exit 1
fi
get_code="$(curl -sS -o /tmp/sec_caldav_get.ics -w '%{http_code}' \
  -u adrians@chezstephens.org.uk:brillig1 \
  "$BASE_URL/caldav/calendars/public/$resource")"
if [ "$get_code" != "200" ]; then
  echo "[security-smoke] FAIL: expected 200 for CalDAV GET on same resource, got $get_code"
  exit 1
fi
missing_code="$(curl -sS -o /tmp/sec_caldav_missing.out -w '%{http_code}' \
  -u adrians@chezstephens.org.uk:brillig1 \
  "$BASE_URL/caldav/calendars/public/999999.ics")"
if [ "$missing_code" != "404" ]; then
  echo "[security-smoke] FAIL: expected 404 for unknown numeric resource, got $missing_code"
  exit 1
fi

echo "[security-smoke] all checks passed"
