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

BASE_URL="${OPENBAO_UI_BASE_URL:-http://127.0.0.1:18200}"
OVERLAY_DIR="${OPENBAO_UI_OVERLAY_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/helm/openbao-ui-overlay}"
CHECK_DRIFT="${CHECK_UPSTREAM_DRIFT:-0}"

ok() { printf '[OK] %s\n' "$*"; }
err() { printf '[ERR] %s\n' "$*" >&2; }
step() { printf '\n==> %s\n' "$*"; }

usage() {
  cat <<'USAGE'
Usage: scripts/openbao-verify-login-overlay.sh [--check-upstream-drift]

Verifies the operator-tunneled OpenBao UI serves the KeyCape login overlay
assets and that index.html injection is present.

Environment:
  OPENBAO_UI_BASE_URL       Operator UI base URL. Default: http://127.0.0.1:18200
  OPENBAO_UI_OVERLAY_DIR    Local overlay directory for drift fingerprints
  CHECK_UPSTREAM_DRIFT      Set to 1 to compare live UI hashes with patches/
USAGE
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --check-upstream-drift)
      CHECK_DRIFT=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      err "unknown argument: $1"
      usage >&2
      exit 2
      ;;
  esac
done

require_pattern() {
  local label="$1"
  local haystack="$2"
  local pattern="$3"
  if ! grep -Eq "$pattern" <<<"$haystack"; then
    err "$label"
    return 1
  fi
  ok "$label"
}

step "Standalone login page"
auth_html="$(curl -fsS "$BASE_URL/ui/vault/auth")"
require_pattern \
  "auth page serves standalone KeyCape login" \
  "$auth_html" \
  'id="login-submit"|Sign in with KeyCape'

if grep -Eq 'vault-|engines-dist' <<<"$auth_html"; then
  err "auth page still serves Ember shell (expected standalone login.html)"
  exit 1
fi
ok "auth page is standalone login.html (no Ember shell)"

callback_html="$(curl -fsS "$BASE_URL/ui/vault/auth/netkingdom/oidc/callback")"
require_pattern \
  "OIDC callback serves standalone handler" \
  "$callback_html" \
  'Signing in with KeyCape|callback.js'

if grep -Eq 'window\.opener\.postMessage|vault-' <<<"$callback_html"; then
  err "OIDC callback still serves Ember shell (expected standalone callback.html)"
  exit 1
fi
ok "OIDC callback is standalone callback.html (no Ember postMessage flow)"

step "Overlay asset endpoints"
index_html="$(curl -fsS "$BASE_URL/ui/")"
overlay_js="$(curl -fsS "$BASE_URL/ui/platform-overlay/overlay.js")"
overlay_css="$(curl -fsS "$BASE_URL/ui/platform-overlay/overlay.css")"
presets_json="$(curl -fsS "$BASE_URL/ui/platform-overlay/presets.json")"

require_pattern \
  "index.html injects overlay.js" \
  "$index_html" \
  '/ui/platform-overlay/overlay\.js'

require_pattern \
  "index.html injects overlay.css" \
  "$index_html" \
  '/ui/platform-overlay/overlay\.css'

require_pattern \
  "overlay.js activates KeyCape overlay" \
  "$overlay_js" \
  'keycape-overlay-active'

require_pattern \
  "overlay.js starts direct KeyCape OIDC redirect" \
  "$overlay_js" \
  'oidc/auth_url'

require_pattern \
  "presets.json targets netkingdom mount" \
  "$presets_json" \
  '"mount"[[:space:]]*:[[:space:]]*"netkingdom"'

require_pattern \
  "presets.json targets platform-admin role" \
  "$presets_json" \
  '"role"[[:space:]]*:[[:space:]]*"platform-admin"'

require_pattern \
  "overlay.css hides namespace picker" \
  "$overlay_css" \
  'toolbar-namespace-picker'

require_pattern \
  "overlay branding title present in presets" \
  "$presets_json" \
  'Sign in with KeyCape'

step "Hidden-field selectors still present in overlay.js"
require_pattern \
  "overlay.js hides namespace input" \
  "$overlay_js" \
  '#namespace|input\[name="namespace"\]'

require_pattern \
  "overlay.js hides role input" \
  "$overlay_js" \
  '#role|input\[name="role"\]'

require_pattern \
  "overlay.js hides mount path input" \
  "$overlay_js" \
  '#custom-path|input\[name="custom-path"\]'

if [ "$CHECK_DRIFT" = "1" ]; then
  step "Upstream UI drift check"
  version_file="$OVERLAY_DIR/VERSION"
  if [ ! -f "$version_file" ]; then
    err "missing overlay VERSION file: $version_file"
    exit 1
  fi
  version="$(tr -d '[:space:]' < "$version_file")"
  manifest="$OVERLAY_DIR/patches/$version/manifest.sha256"
  if [ ! -f "$manifest" ]; then
    err "missing fingerprint manifest: $manifest"
    exit 1
  fi

  vault_asset="$(grep -Eo '/ui/assets/vault-[a-f0-9]+\.js' <<<"$index_html" | head -1 || true)"
  if [ -z "$vault_asset" ]; then
    err "could not locate vault.js asset path in index.html"
    exit 1
  fi
  live_vault_hash="$(curl -fsS "$BASE_URL$vault_asset" | sha256sum | awk '{print $1}')"

  expected_vault_hash="$(awk '!/^#/ && /ui\/assets\/vault-/ {print $1; exit}' "$manifest")"
  expected_vault_path="$(awk '!/^#/ && /ui\/assets\/vault-/ {print $2; exit}' "$manifest")"

  if [ -n "$expected_vault_hash" ] && [ "$live_vault_hash" != "$expected_vault_hash" ]; then
    err "vault bundle hash drift for ${vault_asset:-unknown}: expected $expected_vault_hash got $live_vault_hash"
    exit 1
  fi
  ok "vault bundle hash matches patches/$version/manifest.sha256 (${expected_vault_path:-$vault_asset})"
fi

printf '\nOpenBao login overlay verification passed for %s\n' "$BASE_URL"
