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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

fail() {
  echo "[userfront-loading-policy] $*" >&2
  exit 1
}

if rg -n "FontLoader|assets/fonts/NotoSansKR|_loadBundledFonts" userfront/lib userfront/pubspec.yaml; then
  fail "userfront must not block first render on bundled NotoSansKR font loading"
fi

if rg -n "dotenv\.load|touch \.env" userfront/lib/main.dart userfront/Dockerfile; then
  fail "userfront web startup must not request or create public .env assets"
fi

if rg -n "fontFamily:\s*['\"]NotoSansKR['\"]" userfront/lib; then
  fail "userfront theme must use the platform default font"
fi

if rg -n "await ThemeController\.(app|auth)\.restore" userfront/lib/main.dart; then
  fail "theme restore must not block the first render"
fi

if rg -n "fonts\.googleapis\.com/icon\?family=Material\+Icons" userfront/web/index.html; then
  fail "userfront must not load Google Material Icons stylesheet on the login critical path"
fi

if rg -n -- "--no-tree-shake-icons" userfront/Dockerfile userfront-e2e/package.json; then
  fail "userfront web release build must allow icon tree shaking"
fi

rg -q "optimize-web-build\.mjs" userfront/Dockerfile || fail "Docker build must hash and pre-compress Flutter web entrypoints"
rg -q "nginx-mod-http-brotli" userfront/Dockerfile || fail "runtime image must install the nginx Brotli module"
rg -Fq "main\\.dart\\.[0-9a-f]{12}" userfront/nginx.conf || fail "hashed app entrypoints must use immutable cache"
rg -q "brotli_static\s+on;" userfront/nginx.conf || fail "nginx must serve pre-compressed brotli assets"
rg -q "brotliCompressSync" userfront/scripts/optimize-web-build.mjs || fail "Docker build optimization must generate brotli assets"
rg -q "modulepreload" userfront/scripts/optimize-web-build.mjs || fail "Docker build optimization must preload wasm module entrypoints"
rg -q "canvasKitBaseUrl:\"canvaskit/\"" userfront/scripts/optimize-web-build.mjs || fail "userfront web build must force local CanvasKit instead of fetching engine resources from a CDN"
rg -q "serviceWorkerSettings" userfront/scripts/optimize-web-build.mjs || fail "Flutter service worker registration must be preserved so deployed clients can update cached bundles"
rg -q "serviceWorkerUrl" userfront/scripts/optimize-web-build.mjs || fail "Flutter service worker URL must be explicit so new clients register the worker"
if rg -n "gzip|gzipSync|\\.gz" userfront/nginx.conf userfront/scripts/optimize-web-build.mjs; then
  fail "userfront web compression must be managed as brotli-only"
fi
rg -q "Cache-Control.*no-cache" userfront/nginx.conf || fail "HTML/app shell must use no-cache revalidation"
if rg -n "assets/\\.env|/\\.env|runtimeEnvBody|dotenv\\.load" userfront/lib userfront/nginx.conf userfront-e2e/scripts/serve-userfront-build.mjs; then
  fail "userfront must not request, load, or serve public .env assets to browsers"
fi
if rg -n "/usr/share/nginx/html/.+\\.env|assets/\\.env|cp .+\\.env" docker/docker-compose.staging.template.yaml docker/staging_pull_compose.template.yaml; then
  fail "userfront deployment must not write runtime .env into the public static document root"
fi
rg -q "\\[userfront-runtime\\] BACKEND_URL configured" docker/docker-compose.staging.template.yaml docker/staging_pull_compose.template.yaml || fail "userfront runtime config presence must be logged server-side only"
rg -q "Cache-Control.*immutable" userfront/nginx.conf || fail "versioned static assets must use immutable cache"

tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT

cat > "$tmp_dir/flutter_bootstrap.js" <<'BOOTSTRAP'
const serviceWorkerVersion = "e2e-policy";
_flutter.buildConfig = {
  builds: [
    {
      mainJsPath: "main.dart.js",
      mainWasmPath: "main.dart.wasm",
      jsSupportRuntimePath: "main.dart.mjs",
    },
  ],
};
_flutter.loader.load({
  serviceWorkerSettings: {
    serviceWorkerVersion: serviceWorkerVersion,
  }
});
BOOTSTRAP
cat > "$tmp_dir/index.html" <<'HTML'
<!doctype html>
<html>
  <head></head>
  <body><script src="flutter_bootstrap.js"></script></body>
</html>
HTML
printf 'console.log("js");' > "$tmp_dir/main.dart.js"
printf 'console.log("mjs");' > "$tmp_dir/main.dart.mjs"
printf 'wasm' > "$tmp_dir/main.dart.wasm"
mkdir -p "$tmp_dir/canvaskit/chromium"
printf 'console.log("skwasm");' > "$tmp_dir/canvaskit/skwasm.js"
printf 'skwasm' > "$tmp_dir/canvaskit/skwasm.wasm"
printf 'console.log("canvaskit");' > "$tmp_dir/canvaskit/canvaskit.js"
printf 'canvaskit' > "$tmp_dir/canvaskit/canvaskit.wasm"
printf 'console.log("chromium canvaskit");' > "$tmp_dir/canvaskit/chromium/canvaskit.js"
printf 'chromium canvaskit' > "$tmp_dir/canvaskit/chromium/canvaskit.wasm"
printf 'console.log("skwasm heavy");' > "$tmp_dir/canvaskit/skwasm_heavy.js"
printf 'skwasm heavy' > "$tmp_dir/canvaskit/skwasm_heavy.wasm"

node userfront/scripts/optimize-web-build.mjs "$tmp_dir" >/dev/null
node userfront/scripts/optimize-web-build.mjs "$tmp_dir" >/dev/null

rg -q "serviceWorkerSettings" "$tmp_dir/flutter_bootstrap.js" || fail "optimized bootstrap must keep Flutter service worker settings"
rg -q "serviceWorkerUrl" "$tmp_dir/flutter_bootstrap.js" || fail "optimized bootstrap must register the Flutter service worker on new clients"
rg -q "canvasKitBaseUrl:\"canvaskit/\"" "$tmp_dir/flutter_bootstrap.js" || fail "optimized bootstrap must keep local CanvasKit config"
rg -q "caches\\.open" "$tmp_dir/flutter_service_worker.js" || fail "optimized service worker must cache built assets"
rg -q "networkFirst" "$tmp_dir/flutter_service_worker.js" || fail "optimized service worker must revalidate app shell assets"
if rg -n "unregister\\(" "$tmp_dir/flutter_service_worker.js"; then
  fail "optimized service worker must not unregister itself"
fi
test "$(rg -o "serviceWorkerUrl" "$tmp_dir/flutter_bootstrap.js" | wc -l)" -eq 1 || fail "optimized bootstrap must not duplicate serviceWorkerUrl"
test "$(rg -o "config:\\{canvasKitBaseUrl" "$tmp_dir/flutter_bootstrap.js" | wc -l)" -eq 1 || fail "optimized bootstrap must not duplicate loader config"
rg -q "main\\.dart\\.[0-9a-f]{12}\\.mjs" "$tmp_dir/index.html" || fail "optimized index must preload hashed module entrypoint"
if rg -n '<link rel="preload" href="main\.dart\.[^"]+\.js" as="script" />' "$tmp_dir/index.html"; then
  fail "WASM-capable builds must not preload the JS fallback entrypoint"
fi
test ! -e "$tmp_dir/main.dart.mjs" || fail "plain module entrypoint must be renamed after hashing"
test "$(find "$tmp_dir" -maxdepth 1 -name 'main.dart.*.mjs' | wc -l)" -eq 1 || fail "exactly one hashed module entrypoint must be produced"
if rg -n '"/canvaskit/[^"]+"' "$tmp_dir/flutter_service_worker.js"; then
  fail "service worker install cache must not precache Flutter renderer assets"
fi
if rg -n '"/main\.dart\.[^"]+"' "$tmp_dir/flutter_service_worker.js"; then
  fail "service worker install cache must not duplicate Flutter app entrypoint downloads"
fi
