#!/bin/sh
#
# The React bundle is static: nginx never passes its own environment to it, and
# nothing is baked into the JavaScript at build time any more. This script runs
# at container start, writes the environment Kubernetes gave the pod next to the
# app code, and then hands over to nginx.
#
#   $APP_DIR/.env    KEY="VALUE" lines, for debugging and anything reading dotenv
#   $APP_DIR/env.js  window.__ENV__["KEY"] = "VALUE"; loaded by index.html
#
# $APP_DIR is the nginx web root, so both files are publicly downloadable. Only
# the variables named in NAMIRASOFT_ENVS are written. The pipeline bakes that
# list into the image from the project's .env.template, so everything else the
# pod is handed - secrets mounted through envFrom - stays out of them.
#

set -eu

APP_DIR="${APP_DIR:-/app}"
NAMIRASOFT_ENVS="${NAMIRASOFT_ENVS:-}"

ENV_FILE="$APP_DIR/.env"
ENV_JS_FILE="$APP_DIR/env.js"

# Escapes a value so it is safe inside a double quoted dotenv value and inside a
# double quoted JavaScript string: backslash, double quote and newline.
escape()
{
	printf '%s' "$1" \
		| tr -d '\r' \
		| sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' \
		| awk 'NR > 1 { printf "\\n" } { printf "%s", $0 }'
}

mkdir -p "$APP_DIR"

: > "$ENV_FILE.tmp"
{
	echo "// Generated at container start by entrypoint.sh - do not edit."
	echo "window.__ENV__ = window.__ENV__ || {};"
} > "$ENV_JS_FILE.tmp"

count=0
missing=""
for name in $NAMIRASOFT_ENVS; do
	# printenv tells set apart from empty: a name the pod never provided is
	# reported, a name deliberately set to "" is not.
	if printenv "$name" > /dev/null 2>&1; then
		value=$(escape "$(printenv "$name")")
	else
		value=""
		missing="$missing $name"
	fi
	printf '%s="%s"\n' "$name" "$value" >> "$ENV_FILE.tmp"
	printf 'window.__ENV__["%s"] = "%s";\n' "$name" "$value" >> "$ENV_JS_FILE.tmp"
	count=$((count + 1))
done

mv "$ENV_FILE.tmp" "$ENV_FILE"
mv "$ENV_JS_FILE.tmp" "$ENV_JS_FILE"

if [ "$count" -eq 0 ]; then
	echo "[entrypoint] NAMIRASOFT_ENVS is empty, the app gets no environment at all - does the project have a .env.template?"
else
	echo "[entrypoint] wrote $count variable(s) to $ENV_FILE and $ENV_JS_FILE"
fi

if [ -n "$missing" ]; then
	echo "[entrypoint] listed in .env.template but not set on the pod, written empty:$missing"
fi

# nginx serves *.js with a one year immutable cache, so point index.html at a new
# env.js?v= on every change, otherwise browsers keep the environment of the
# deployment they first loaded.
if [ -f "$APP_DIR/index.html" ]; then
	version=$(md5sum "$ENV_JS_FILE" | cut -c1-8)
	sed -i "s|env\\.js?v=[^\"]*|env.js?v=$version|" "$APP_DIR/index.html"
fi

# Anything passed to the container wins, otherwise start nginx (the image CMD).
if [ "$#" -gt 0 ]; then
	exec "$@"
fi

exec nginx -g "daemon off;"
