#!/usr/bin/env bash
set -Eeuo pipefail
WWW='www.learnitive.com'
APEX='learnitive.com'
EDU='edu.learnitive.com'
resolve_www=(--resolve "$WWW:443:127.0.0.1")
resolve_apex=(--resolve "$APEX:443:127.0.0.1")
resolve_edu=(--resolve "$EDU:443:127.0.0.1")
fail(){ printf '[Learnitive www local verify] ERROR: %s\n' "$*" >&2; exit 1; }
request(){ curl --noproxy '*' --silent --show-error --max-time 12 "$@"; }
status(){ curl --noproxy '*' --silent --show-error --max-time 12 --output /dev/null --write-out '%{http_code}' "$@"; }
headers(){ curl --noproxy '*' --silent --show-error --max-time 12 --head "$@" | tr -d '\r'; }
location_header(){ awk 'BEGIN { IGNORECASE=1 } /^location:[[:space:]]*/ { sub(/^[^:]*:[[:space:]]*/, ""); print; exit }'; }
assert_redirect(){
  local label="$1" response="$2" expected="$3" actual
  grep -Eq '^HTTP/[^ ]+ 301' <<<"$response" || fail "$label does not return 301."
  actual="$(location_header <<<"$response")"
  [[ "$actual" == "$expected" ]] || fail "$label Location mismatch: expected $expected; got ${actual:-<missing>}"
}

http_www_headers="$(headers --resolve "$WWW:80:127.0.0.1" "http://$WWW/features?cutover=1")"
assert_redirect 'www HTTP' "$http_www_headers" 'https://www.learnitive.com/features?cutover=1'

http_apex_headers="$(headers --resolve "$APEX:80:127.0.0.1" "http://$APEX/features?cutover=1")"
assert_redirect 'apex HTTP' "$http_apex_headers" 'https://www.learnitive.com/features?cutover=1'

http_edu_headers="$(headers --resolve "$EDU:80:127.0.0.1" "http://$EDU/features?cutover=1")"
assert_redirect 'edu HTTP after production cutover' "$http_edu_headers" 'https://www.learnitive.com/features?cutover=1'

code="$(status "${resolve_www[@]}" "https://$WWW/features")"
[[ "$code" == 200 ]] || fail "/features returned $code"
body="$(request "${resolve_www[@]}" "https://$WWW/features")"
grep -Eqi '<title>[^<]*Features[^<]*Learnitive</title>' <<<"$body" || fail '/features title is not route-specific.'
grep -Fq 'https://www.learnitive.com/features' <<<"$body" || fail '/features canonical is not www.'
if grep -Eqi 'href="/learn"[^>]*>[[:space:]]*Learn[[:space:]]*<' <<<"$body"; then fail 'public top navigation still exposes the removed Learn link.'; fi
feature_headers="$(headers "${resolve_www[@]}" "https://$WWW/features")"
if grep -Eqi '^x-robots-tag: .*noindex' <<<"$feature_headers"; then fail 'production www must not inherit the staging X-Robots-Tag noindex header.'; fi
grep -Eqi '^content-security-policy: .*wss://www\.learnitive\.com' <<<"$feature_headers" || fail 'production CSP does not allow the www WebSocket origin.'

manifest_code="$(status "${resolve_www[@]}" "https://$WWW/manifest.json")"
[[ "$manifest_code" == 200 ]] || fail "/manifest.json returned $manifest_code"
manifest_headers="$(headers "${resolve_www[@]}" "https://$WWW/manifest.json")"
grep -Eqi '^content-type: application/(manifest\+json|json)' <<<"$manifest_headers" || fail '/manifest.json has the wrong content type.'

code="$(status "${resolve_www[@]}" "https://$WWW/__www-cutover-missing-page__")"
[[ "$code" == 404 ]] || fail "unknown URL returned $code instead of 404"
missing="$(request "${resolve_www[@]}" "https://$WWW/__www-cutover-missing-page__")"
grep -Eqi 'name="robots"[^>]*content="[^"]*noindex|content="[^"]*noindex[^"]*"[^>]*name="robots"' <<<"$missing" || fail '404 response is missing noindex.'

admin="$(request "${resolve_www[@]}" "https://$WWW/admin")"
grep -Eqi 'name="robots"[^>]*content="[^"]*noindex|content="[^"]*noindex[^"]*"[^>]*name="robots"' <<<"$admin" || fail '/admin initial HTML is not noindex.'
projects="$(request "${resolve_www[@]}" "https://$WWW/projects")"
grep -Eqi 'name="robots"[^>]*content="[^"]*noindex|content="[^"]*noindex[^"]*"[^>]*name="robots"' <<<"$projects" || fail '/projects initial HTML is not noindex.'

robots="$(request "${resolve_www[@]}" "https://$WWW/robots.txt")"
grep -Fq "Sitemap: https://$WWW/sitemap.xml" <<<"$robots" || fail 'robots.txt does not reference the www sitemap.'
sitemap="$(request "${resolve_www[@]}" "https://$WWW/sitemap.xml")"
grep -Fq "https://$WWW/" <<<"$sitemap" || fail 'sitemap has no www canonical URLs.'
if grep -Eq 'https://((edu|os)\.)?learnitive\.com/' <<<"$sitemap"; then fail 'sitemap contains staging, legacy os, or apex canonical URLs.'; fi

privacy_headers="$(headers "${resolve_www[@]}" "https://$WWW/pages/privacy")"
assert_redirect '/pages/privacy' "$privacy_headers" 'https://www.learnitive.com/privacy'

apex_headers="$(headers "${resolve_apex[@]}" "https://$APEX/features?cutover=1")"
assert_redirect 'apex HTTPS' "$apex_headers" 'https://www.learnitive.com/features?cutover=1'

edu_headers="$(headers "${resolve_edu[@]}" "https://$EDU/features?cutover=1")"
assert_redirect 'edu HTTPS after production cutover' "$edu_headers" 'https://www.learnitive.com/features?cutover=1'

compare="$(request "${resolve_www[@]}" "https://$WWW/compare/overleaf")"
grep -Fq 'data-interactive-prerender=' <<<"$compare" || fail '/compare/overleaf lacks substantive initial HTML.'

# The core application installer deliberately certifies the Console Gateway over
# loopback during a www promotion because the new production vhost is not active
# until this verifier runs. Now that Apache has been cut over, certify the real
# public WSS route all the way through Console Gateway -> Docker -> PTY before
# install-www-vhosts.sh commits the cutover. The smoke creates and destroys only
# its own Learnitive guest sandbox.
CONSOLE_ENV='/etc/learnitive/console-gateway.env'
HOST_NODE='/var/www/learnitive.com/.learnitive-runtime/bin/node'
TERMINAL_SMOKE='/var/www/learnitive.com/public_html/learnitive-services/console-gateway/terminal-smoke.mjs'
CONSOLE_USER='learnitive-os-console'
[[ -r "$CONSOLE_ENV" ]] || fail 'Console Gateway environment is not readable for post-cutover WSS certification.'
[[ -x "$HOST_NODE" ]] || fail 'Validated Learnitive runtime Node is missing for post-cutover WSS certification.'
[[ -f "$TERMINAL_SMOKE" ]] || fail 'Cloud Terminal smoke helper is missing for post-cutover WSS certification.'
command -v runuser >/dev/null 2>&1 || fail 'runuser is required for post-cutover WSS certification.'
console_secret="$(awk -F= '$1 == "LEARNITIVE_CONSOLE_GATEWAY_SECRET" { sub(/^[^=]*=/, ""); print; exit }' "$CONSOLE_ENV")"
[[ -n "$console_secret" ]] || fail 'Console Gateway secret is missing for post-cutover WSS certification.'
if ! runuser -u "$CONSOLE_USER" -- env \
  LEARNITIVE_CONSOLE_GATEWAY_URL='http://127.0.0.1:9887' \
  LEARNITIVE_CONSOLE_GATEWAY_SECRET="$console_secret" \
  LEARNITIVE_CONSOLE_PUBLIC_ORIGIN="https://$WWW" \
  "$HOST_NODE" "$TERMINAL_SMOKE"; then
  fail 'www Cloud Terminal public HTTPS WebSocket -> Console Gateway -> Docker -> PTY certification failed.'
fi
printf '[Learnitive www local verify] Cloud Terminal public WSS + PTY certification passed through www.learnitive.com.\n'

printf '[Learnitive www local verify] PASS: www production, apex + edu one-hop redirects, canonical metadata, private noindex, sitemap/robots, top-navigation and Cloud Terminal WSS cutover verified on 127.0.0.1.\n'
