#!/bin/sh
# Spawned by forkd-agent.py via FORKD_WARMUP_CMD before the parent
# snapshot is taken. Delegates to upstream docker-entrypoint.sh for
# the heavy lifting (initdb, /docker-entrypoint-initdb.d/, password
# config), then emits the line-JSON ready handshake and parks.
#
# Stdout is the agent's handshake channel: the FIRST line on stdout
# must be {"ready": true}. Everything else goes to a log file so it
# does not confuse the agent. Stderr stays intact for visibility.
#
# Configuration is read from /etc/forkd-recipe.env at startup
# (PG_USER, PG_PASSWORD, PG_DATABASE).

set -e

# The Debian postgres image puts binaries under
# /usr/lib/postgresql/16/bin/ and adds them to PATH via the image's
# ENV. forkd-agent inherits a minimal PATH so we restore it
# explicitly here so initdb, pg_ctl, psql resolve.
export PATH=/usr/lib/postgresql/16/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# docker-entrypoint.sh uses bash process substitution (<(printf ...))
# to pass the postgres password to initdb. That writes to /dev/fd/63.
# In a Debian rootfs /dev/fd is normally a symlink to /proc/self/fd,
# but forkd's devtmpfs setup doesn't create it. Make sure it exists.
[ -e /dev/fd ] || ln -s /proc/self/fd /dev/fd

# Read recipe env if present; build.sh writes it alongside this script.
if [ -f /etc/forkd-recipe.env ]; then
    . /etc/forkd-recipe.env
fi

export PGDATA=/var/lib/postgresql/data
export POSTGRES_USER="${PG_USER:-forkd}"
export POSTGRES_PASSWORD="${PG_PASSWORD:-forkd}"
export POSTGRES_DB="${PG_DATABASE:-forkd_test}"
export POSTGRES_HOST_AUTH_METHOD=trust

# Start postgres via upstream docker-entrypoint. The script runs
# initdb the first time (idempotent on existing PGDATA), then execs
# the postmaster. We background it and silence its stdout so only
# our handshake reaches the agent.
docker-entrypoint.sh postgres -c listen_addresses='*' >/tmp/pg-entry.log 2>&1 &
ENTRY_PID=$!

# Wait up to 30 s for the postmaster to accept connections on TCP.
# The wait probes as $POSTGRES_USER (not "postgres") because initdb
# creates only the configured app role, not a separate postgres role.
i=0
while [ $i -lt 60 ]; do
    if su postgres -c "psql -h 127.0.0.1 -U \"$POSTGRES_USER\" -d postgres -tAc 'SELECT 1' >/dev/null 2>&1"; then
        break
    fi
    sleep 0.5
    i=$((i + 1))
done

# Signal ready to forkd-agent. Snapshot will be taken shortly after,
# capturing the postmaster's resident memory + open sockets.
echo '{"ready": true}'

# Park alive: agent uses this PID for lifecycle correlation;
# postgres runs in the background and is what children inherit.
wait $ENTRY_PID
