#!/usr/bin/env bash
#
# Build and deploy the storefront to a web-root directory.
#
#   projects/storefront/deploy/deploy.sh /home/moonui4/public_html/store moonui4
#
# Why this exists as a script rather than a paragraph of instructions:
#
#   1. `assets/config.json` is gitignored, and the Angular asset copier SKIPS
#      gitignored files. A clean build therefore emits `config.json.example`
#      but NOT `config.json`, and the app refuses to boot without it — it shows
#      the config-error screen. That is deliberate (an instance's `apiUrl` must
#      never be baked into a bundle that could be copied elsewhere), but it
#      means a hand-run `ng build && cp` produces a DEAD app on any target that
#      does not already have the file. Verified twice on 2026-07-20.
#
#   2. `.htaccess` and `assets/config.json` live ONLY in the deploy target, not
#      in the build output. A `rm -rf target/*` wipes them and the SPA stops
#      routing. The clean-up below is therefore globbed to top-level build
#      artefacts only.
#
# The script fails loudly rather than deploying something that cannot boot.

set -euo pipefail

TARGET="${1:?usage: deploy.sh <target-dir> [owner]}"
OWNER="${2:-}"
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
DIST="$REPO_ROOT/dist/storefront/browser"
SRC_CONFIG="$REPO_ROOT/projects/storefront/src/assets/config.json"
ROOT_POLICY="$REPO_ROOT/projects/storefront/deploy/root-seo-bridge.template"
ROOT_HTACCESS="$(dirname "$TARGET")/.htaccess"

cd "$REPO_ROOT"

[ -d "$TARGET" ] || { echo "FATAL: target '$TARGET' does not exist"; exit 1; }

# --- 1. The runtime config must exist BEFORE we spend time building ----------
if [ ! -f "$TARGET/assets/config.json" ] && [ ! -f "$SRC_CONFIG" ]; then
  echo "FATAL: no runtime config found."
  echo "  Neither $TARGET/assets/config.json"
  echo "  nor    $SRC_CONFIG"
  echo "Copy assets/config.json.example to one of them and set apiUrl first."
  exit 1
fi

# --- 2. Build (baseHref is pinned in angular.json — no flag needed) ----------
echo "==> building"
npx ng build storefront

grep -q '<base href="/store/"' "$DIST/index.html" || {
  echo "FATAL: built index.html does not carry <base href=\"/store/\">."
  echo "Check the storefront build options in angular.json."
  exit 1
}

# --- 3. Replace build artefacts, preserving .htaccess and assets/config.json -
echo "==> deploying to $TARGET"
rm -f "$TARGET"/*.js "$TARGET"/*.css "$TARGET"/*.html "$TARGET"/*.ico
cp -rf "$DIST"/* "$TARGET"/

# --- 4. Restore the runtime config the build could not emit ------------------
if [ ! -f "$TARGET/assets/config.json" ]; then
  echo "==> target had no config.json; installing from src"
  cp "$SRC_CONFIG" "$TARGET/assets/config.json"
fi

# --- 5. Install the versioned routing/security policy ------------------------
# .htaccess is a deployment artefact, not tenant data. Refresh it on every
# release so renderer, cache, and security fixes reach every Moon instance.
#
# The source is `projects/storefront/public/.htaccess`, which the Angular build
# copies into dist/ — NOT `deploy/htaccess.template`, which is retired. Shipping
# the template installed a file with the SPA fallback and the SEO-renderer rules
# both absent, so every deep link under /store (…/products, …/categories) 404'd
# while only the bare index resolved. Copy what the build produced.
echo "==> installing .htaccess policy"
if [ -f "$DIST/.htaccess" ]; then
  cp "$DIST/.htaccess" "$TARGET/.htaccess"
else
  echo "FATAL: dist/.htaccess is missing — the build did not copy projects/storefront/public/.htaccess"
  exit 1
fi

# robots.txt and sitemap XML belong at the origin root, outside /store/. Keep a
# delimited policy block at the TOP of the root file so an existing catch-all
# cannot consume these requests first. Tenant rules outside the block survive.
echo "==> installing root SEO discovery bridge"
ROOT_TMP="$(mktemp "$(dirname "$ROOT_HTACCESS")/.htaccess.storefront-seo.XXXXXX")"
{
  cat "$ROOT_POLICY"
  if [ -f "$ROOT_HTACCESS" ]; then
    awk '
      /^# BEGIN Moon Storefront SEO Discovery$/ { managed=1; next }
      /^# END Moon Storefront SEO Discovery$/ { managed=0; next }
      !managed { print }
    ' "$ROOT_HTACCESS"
  fi
} > "$ROOT_TMP"
if [ -f "$ROOT_HTACCESS" ]; then
  chmod --reference="$ROOT_HTACCESS" "$ROOT_TMP"
fi
mv "$ROOT_TMP" "$ROOT_HTACCESS"

if [ -n "$OWNER" ]; then
  chown -R "$OWNER:$OWNER" "$TARGET"
  chown "$OWNER:$OWNER" "$ROOT_HTACCESS"
fi

# --- 6. Prove the deployed app can actually boot -----------------------------
echo "==> verifying"
API="$(python3 -c "import json;print(json.load(open('$TARGET/assets/config.json'))['apiUrl'])")"
echo "    apiUrl        : $API"
echo "    base href     : $(grep -o '<base href="[^"]*"' "$TARGET/index.html")"
echo "    .htaccess     : $([ -f "$TARGET/.htaccess" ] && echo present || echo MISSING)"
grep -q '/moon-erp-be/storefront-seo' "$TARGET/.htaccess" || {
  echo "FATAL: storefront SEO renderer rewrite is missing from .htaccess"
  exit 1
}
grep -q '^# BEGIN Moon Storefront SEO Discovery$' "$ROOT_HTACCESS" || {
  echo "FATAL: root SEO discovery bridge is missing from $ROOT_HTACCESS"
  exit 1
}
echo "    config.json   : present"
echo
echo "Deployed. Confirm the apiUrl above belongs to THIS instance —"
echo "a config pointing at another instance's backend fails silently."
