#!/usr/bin/env bash

set -eu
me="$(readlink -f "$0")"
here="${me%/*}"
me="${me##*/}"

# This is a prototype and will probably not survive in its current form.
# Don't rely on it.

force=
info=
rendezvous=
suite=
use_timestamp=
verbose=

if [ "${STEAM_LINUX_RUNTIME_VERBOSE-}" = 1 ]; then
    verbose=yes
    # Propagate it to pressure-vessel too
    export PRESSURE_VESSEL_VERBOSE=1
fi

if [ "${STEAM_LINUX_RUNTIME_LOG-}" = 1 ]; then
    # If we are logging to a file, use the timestamp
    info=yes
    use_timestamp=yes
fi

log () {
    if [ -n "$use_timestamp" ]; then
        printf '%s\n' "$(LD_PRELOAD='' date +'%H:%M:%S.%6N'): ${me}[$$]: $*" >&2
    else
        printf '%s\n' "${me}[$$]: $*" >&2
    fi
}

info () {
    if [ -n "${info}${verbose}" ]; then
        log "$@"
    fi
}

verbose () {
    if [ -n "$verbose" ]; then
        log "$@"
    fi
}

info "argv: $(printf '%q ' "$@")"

usage () {
    local code="$1"
    shift

    if [ "$code" -ne 0 ]; then
        exec >&2
    fi

    echo "Usage:"
    echo "$me [OPTIONS] [-- [PVL_OPTIONS]]"
    echo
    echo "Must be run while holding a lock."
    echo
    echo "Options"
    echo "--deploy=DIR      Ignored for backwards compatibility."
    echo "--force           Try even if an earlier attempt failed."
    echo "--session=PATH    Directory representing a session."
    echo "--suite=SUITE     Run in this runtime [default=choose automatically]."
    echo "--use-timestamp   Prepend the timestamp to the log entries."
    echo "--verbose         Be more verbose."

    exit "${code}"
}

getopt_temp="help"
getopt_temp="${getopt_temp},deploy:"
getopt_temp="${getopt_temp},force"
getopt_temp="${getopt_temp},session:"
getopt_temp="${getopt_temp},suite:"
getopt_temp="${getopt_temp},use-timestamp:"
getopt_temp="${getopt_temp},verbose"

getopt_temp="$(getopt -o '' --long "$getopt_temp" -n "$me" -- "$@")"
eval "set -- $getopt_temp"
unset getopt_temp

while [ "$#" -gt 0 ]; do
    case "$1" in
        (--help)
            usage 0
            # not reached
            ;;

        (--deploy)
            shift 2
            ;;

        (--force)
            force=yes
            shift
            ;;

        (--session)
            rendezvous="$2"
            shift 2
            ;;

        (--suite)
            suite="$2"
            shift 2
            ;;

        (--use-timestamp)
            use_timestamp=yes
            shift
            ;;

        (--verbose)
            verbose=yes
            # Propagate it to pressure-vessel too
            export PRESSURE_VESSEL_VERBOSE=1
            shift
            ;;

        (--)
            shift
            break
            ;;

        (-*)
            log "Unknown option: $1"
            usage 64    # EX_USAGE from sysexits.h
            # not reached
            ;;

        (*)
            break
            ;;
    esac
done

pressure_vessel="${PRESSURE_VESSEL_PREFIX:-"${here}/pressure-vessel"}"

if [ -z "$rendezvous" ]; then
    log "A session path is required"
    exit 64
fi

if [ -S "$rendezvous/socket" ]; then
    info "Session already started in $rendezvous"
    exit 0
fi

if [ -z "$force" ] && [ -e "$rendezvous/failed" ]; then
    log "Starting session already failed, not trying again."
    log "Remove $rendezvous/failed to retry."
    exit 70     # EX_SOFTWARE
fi

rm -f "$rendezvous/fifo"
mkfifo "$rendezvous/fifo"

if [ -z "${suite}" ]; then
    run=run
else
    run="run-in-${suite}"
fi

info "Starting pressure-vessel-launcher in background"
"${here}/${run}" \
    --filesystem="$pressure_vessel" \
    --filesystem="$rendezvous" \
    --launcher \
    --pass-fd=3 \
    "$@" \
    -- \
        --info-fd=3 \
        --socket-directory="$rendezvous" \
        < /dev/null >&2 3>"$rendezvous/fifo" &
container_pid="$!"
info "Started pressure-vessel-launcher in background, pid $container_pid"
socket=$(
    while read -r line; do
        case "$line" in
            (socket=*)
                echo "${line#socket=}"
                break
                ;;
        esac
    done < "$rendezvous/fifo"
)

if [ -z "$socket" ] || ! [ -S "$socket" ]; then
    : > "$rendezvous/failed"
    log "Error starting pressure-vessel container"
    if [ -z "${STEAM_LINUX_RUNTIME_VERBOSE-}" ]; then
        log "Try environment variable STEAM_LINUX_RUNTIME_VERBOSE=1 for more details"
    fi
    kill "$container_pid" || :
    exit 70     # EX_SOFTWARE
fi

ln -fns "$socket" "$rendezvous/socket"
verbose "OK, ready to exit"
exit 0

# vim:set sw=4 sts=4 et:
