#!/usr/bin/env bash
# Verify the public config and every public image/design asset through a running
# backend. Run after PM2 restarts for initial deployments and backend hot fixes.

set -Eeuo pipefail

API_BASE="${1:-http://127.0.0.1:3000}"
API_BASE="${API_BASE%/}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TMP_DIR="$(mktemp -d)"
CONFIG_JSON="$TMP_DIR/config.json"
TEMPLATE_URLS="$TMP_DIR/template-urls.txt"
DESIGN_MANIFEST="$TMP_DIR/postcard-design-manifest.json"

cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT

die() {
  echo "ERROR: $*" >&2
  exit 1
}

request_no_redirect() {
  local path="$1" label="${2:-$1}" quiet="${3:-}" separator='?'
  [[ "$path" == *'?'* ]] && separator='&'

  local result code redirect
  result="$(curl --silent --show-error --output /dev/null \
    --write-out '%{http_code}\t%{redirect_url}' \
    -H 'Cache-Control: no-cache' \
    "$API_BASE$path${separator}smoke=$(date +%s%N)" || true)"
  code="${result%%$'\t'*}"
  redirect="${result#*$'\t'}"

  [[ "$code" == "200" ]] || die "$label returned HTTP ${code:-000}"
  [[ -z "$redirect" ]] || die "$label redirected to $redirect"
  [[ "$quiet" == "quiet" ]] || echo "OK: $label -> 200 without redirect"
}

if [[ "$API_BASE" == http://127.0.0.1:* || "$API_BASE" == http://localhost:* ]]; then
  RUNTIME_LABEL="LOCAL RUNTIME"
else
  RUNTIME_LABEL="PUBLIC RUNTIME"
fi

echo
echo "$RUNTIME_LABEL: $API_BASE"

config_result="$(curl --silent --show-error --output "$CONFIG_JSON" \
  --write-out '%{http_code}\t%{redirect_url}\t%{content_type}' \
  -H 'Cache-Control: no-cache' \
  "$API_BASE/api/config?smoke=$(date +%s%N)" || true)"
config_code="${config_result%%$'\t'*}"
config_rest="${config_result#*$'\t'}"
config_redirect="${config_rest%%$'\t'*}"
config_type="${config_rest#*$'\t'}"

[[ "$config_code" == "200" ]] || die "/api/config returned HTTP ${config_code:-000}"
[[ -z "$config_redirect" ]] || die "/api/config redirected to $config_redirect"
[[ "$config_type" == application/json* ]] || die "/api/config returned unexpected content type: $config_type"

node - "$CONFIG_JSON" "$TEMPLATE_URLS" <<'NODE'
const fs = require('fs');
const [configPath, outputPath] = process.argv.slice(2);
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

function requireRelativeApiUrl(value, label) {
  if (typeof value !== 'string' || !value.startsWith('/api/')) {
    throw new Error(`${label} must be a relative /api URL: ${JSON.stringify(value)}`);
  }
  if (/^https?:\/\//i.test(value) || value.startsWith('//')) {
    throw new Error(`${label} must not be absolute: ${value}`);
  }
}

requireRelativeApiUrl(config.logoUrl, 'logoUrl');

if (!Array.isArray(config.templates) || config.templates.length === 0) {
  throw new Error('/api/config returned no templates');
}

const urls = config.templates.map((template, index) => {
  requireRelativeApiUrl(template.url, `templates[${index}].url`);
  if (!template.url.startsWith('/api/templates/image/')) {
    throw new Error(`templates[${index}].url uses the wrong endpoint: ${template.url}`);
  }
  return template.url;
});

fs.writeFileSync(outputPath, [...new Set(urls)].join('\n') + '\n');
NODE

logo_url="$(node -p "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8')).logoUrl" "$CONFIG_JSON")"
request_no_redirect "$logo_url" "logo image" quiet

template_count=0
while IFS= read -r template_url; do
  [[ -n "$template_url" ]] || continue
  request_no_redirect "$template_url" "template image: $template_url" quiet
  template_count=$((template_count + 1))
done < "$TEMPLATE_URLS"
echo "  OK Config: $template_count relative templates"
echo "  OK Images: logo + $template_count templates"

bash "$SCRIPT_DIR/smoke-test-ui-assets.sh" "$API_BASE"

request_no_redirect "/api/postcard-template" "postcard template" quiet

health_json="$(curl --fail --silent --show-error \
  "$API_BASE/api/postcard-design/health?smoke=$(date +%s%N)")" \
  || die "postcard design health request failed"
design_version="$(node -e '
  const fs = require("fs");
  const health = JSON.parse(fs.readFileSync(0, "utf8"));
  if (health.ok !== true) throw new Error("postcard design health is not ok");
  process.stdout.write(health.version || "unknown");
' <<<"$health_json")"

request_no_redirect "/api/postcard-design/main.css" "postcard design CSS" quiet
request_no_redirect "/api/postcard-design/fonts.css" "postcard font CSS" quiet

curl --fail --silent --show-error \
  "$API_BASE/api/postcard-design/manifest.json?smoke=$(date +%s%N)" \
  -o "$DESIGN_MANIFEST" \
  || die "postcard design manifest request failed"

font_count=0
while IFS= read -r font_file; do
  [[ -n "$font_file" ]] || continue
  request_no_redirect "/api/postcard-design/fonts/$font_file" "postcard font: $font_file" quiet
  font_count=$((font_count + 1))
done < <(node -e '
  const fs = require("fs");
  const manifest = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
  for (const file of manifest.fontFiles || []) console.log(file);
' "$DESIGN_MANIFEST")
echo "  OK Postcard: template + 2 stylesheets + $font_count fonts"
echo "  OK Design: $design_version"
echo "  RESULT: HEALTHY — all requests returned 200 without redirects"

