#!/bin/sh
# Writes the configuration PostgREST is to read: the NAME=value lines of the
# source are expanded into the rest of it and left out of the result.
#
# Those lines are ours. PostgREST's own keys hold a dash and spaces around
# the =, so the two never look alike, and a secret can live in the one file
# it belongs to instead of a command line or the environment, where ps and a
# stray env would show it.
#
# Nothing is evaluated: a value is copied as it stands, so a password holding
# $, a backtick or a quote is no different from any other.
set -e

usage="usage: ${0##*/} SOURCE TARGET"
src=${1:?$usage}
dst=${2:?$usage}

fail() {
	echo "${0##*/}: $*" >&2
	exit 1
}

assignments='^[A-Za-z_][A-Za-z_0-9]*='
# Comments are left exactly as they are, and read as nothing: they document
# the variables, so they name them, and a value has no business being copied
# into a comment in the first place.
comments='^[[:space:]]*#'

# A value runs to the end of the line, so it may hold spaces; a single pair
# of quotes around it is dropped, which is how leading or trailing spaces
# are written. An empty one is the state the package ships in, and the whole
# reason this script reports rather than starts.
script=
names=
while IFS= read -r line; do
	# A file with no assignments at all still sends one empty line through.
	[ -n "$line" ] || continue
	name=${line%%=*}
	value=${line#*=}
	case $value in
		\"*\") value=${value#\"}; value=${value%\"} ;;
		\'*\') value=${value#\'}; value=${value%\'} ;;
	esac
	[ -n "$value" ] || fail "set $name in $src"
	# & and \ carry meaning in a sed replacement, | is the delimiter here.
	value=$(printf '%s' "$value" | sed 's/[\\&|]/\\&/g')
	script="$script;s|\${$name}|$value|g;s|\$$name|$value|g"
	names="$names $name"
done <<EOF
$(sed -n "/$assignments/p" "$src")
EOF

# What is referred to but never assigned, looked for before the values go in
# rather than after: a password is free to hold a $ of its own.
for ref in $(sed -e "/$assignments/d" -e "/$comments/d" "$src" |
		grep -o '\${\{0,1\}[A-Za-z_][A-Za-z_0-9]*' | tr -d '${' | sort -u); do
	case " $names " in
		*" $ref "*) ;;
		*) fail "$ref is used but not set in $src" ;;
	esac
done

if [ -n "$script" ]; then
	set -- -e "/$assignments/d" -e "/$comments/!{${script#;};}"
else
	set -- -e "/$assignments/d"
fi
# Readable by the group PostgREST runs as, as the source is, and no wider.
(umask 027; sed "$@" "$src" > "$dst")
chgrp ohlcdb-web "$dst" 2>/dev/null || :
