#!/bin/sh
# fgfs-run - single entry point for all FlightGear backends on Sailfish OS.
#
#   fgfs-run [--backend=zink|gles2|gles3] [--region=LAT,LON[,RADIUS]] [fgfs options...]
#
# Picks the library paths and environment for the chosen backend, optionally
# fetches the scenery for a region first, and execs the matching binary.
# Without --backend it uses FGFS_BACKEND, or zink, which is the only backend
# with the PUI menus, the HUD and the canvas displays.
#
# POSIX shell on purpose: /bin/bash on the device is not a full bash and has
# no arrays.
set -e

BACKEND=${FGFS_BACKEND:-zink}
REGION=""
RADIUS=1
FGROOT=${FGFS_ROOT:-$HOME/.local/share/harbour-fgview/fgdata}
SCENERY=${FGFS_SCENERY:-$HOME/.fgfs/TerraSync}

# Collect the options meant for fgfs in the positional parameters.
collected=""
for arg in "$@"; do
    case "$arg" in
        --backend=*) BACKEND="${arg#*=}"; continue ;;
        --region=*)  REGION="${arg#*=}"; continue ;;
        --fg-root=*) FGROOT="${arg#*=}" ;;
        --list-backends)
            echo "zink   /opt/fgfs         Mesa/Zink, full feature set (menus, HUD, canvas)"
            echo "gles2  /opt/fgfs-gles    native GLES2, no fixed-function features"
            echo "gles3  /opt/fgfs-gles3   native GLES3, no fixed-function features"
            exit 0 ;;
    esac
    collected="$collected $arg"
done
# shellcheck disable=SC2086
set -- $collected

# --- pick up the scenery for a region before starting -----------------------
if [ -n "$REGION" ]; then
    LAT=${REGION%%,*}
    REST=${REGION#*,}
    LON=${REST%%,*}
    case "$REST" in *,*) RADIUS=${REST##*,} ;; esac
    echo "fgfs-run: Szenerie fuer $LAT,$LON (Radius $RADIUS Grad) wird geprueft ..."
    if [ -x /opt/fgfs/bin/fgfs-scenery ]; then
        /opt/fgfs/bin/fgfs-scenery --lat "$LAT" --lon "$LON" --radius "$RADIUS" \
            --target "$SCENERY" --subtrees Terrain,Objects || \
            echo "fgfs-run: Szenerie-Abgleich fehlgeschlagen, starte mit dem vorhandenen Bestand"
    else
        echo "fgfs-run: fgfs-scenery fehlt, ueberspringe den Abgleich" >&2
    fi
fi
[ -d "$SCENERY/Terrain" ] && set -- "$@" "--fg-scenery=$SCENERY"

# --- backend specific environment -------------------------------------------
# The install prefixes are not consistent about lib vs lib64, and a prefix can
# have both, so take every directory that exists rather than guessing one.
libdirs() {
    out=""
    for prefix in "$@"; do
        for d in "$prefix/lib64" "$prefix/lib"; do
            [ -d "$d" ] || continue
            if [ -z "$out" ]; then out="$d"; else out="$out:$d"; fi
        done
    done
    echo "$out"
}

# The osgPlugins directory sits next to libosg, wherever that turned out to be.
plugindir() {
    for prefix in "$@"; do
        for d in "$prefix/lib64" "$prefix/lib"; do
            for p in "$d"/osgPlugins-*; do
                [ -d "$p" ] && { echo "$p"; return; }
            done
        done
    done
}

case "$BACKEND" in
    zink)
        PREFIX=/opt/fgfs
        LD_LIBRARY_PATH="$(libdirs /opt/mesa-zink /opt/fgfs)"
        __EGL_VENDOR_LIBRARY_DIRS=/opt/mesa-zink/share/glvnd/egl_vendor.d
        MESA_LOADER_DRIVER_OVERRIDE=zink
        # lazy descriptors are worth about 30 percent on the Mali
        ZINK_DESCRIPTORS=${ZINK_DESCRIPTORS:-lazy}
        export LD_LIBRARY_PATH __EGL_VENDOR_LIBRARY_DIRS MESA_LOADER_DRIVER_OVERRIDE ZINK_DESCRIPTORS
        unset GALLIUM_DRIVER
        ;;
    gles2|gles3)
        if [ "$BACKEND" = gles2 ]; then
            PREFIX=/opt/fgfs-gles; OSGDIR=/opt/osg-gles
        else
            PREFIX=/opt/fgfs-gles3; OSGDIR=/opt/osg-gles3
        fi
        LD_LIBRARY_PATH="$(libdirs "$OSGDIR" "$PREFIX")"
        OSG_LIBRARY_PATH="$(plugindir "$OSGDIR" "$PREFIX")"
        # the device EGL stack has no dma-heap we could import from
        FGFS_DMA_HEAP=${FGFS_DMA_HEAP:-/dev/null}
        export LD_LIBRARY_PATH OSG_LIBRARY_PATH FGFS_DMA_HEAP
        # Draw on its own thread: the update phase then overlaps with the
        # draw, measured 84 -> 47 ms per frame.  FGFS_THREADING overrides.
        set -- "$@" "--prop:/sim/rendering/multithreading-mode=${FGFS_THREADING:-DrawThreadPerContext}"
        # 60 Hz flight model: plenty for light aircraft, half the JSBSim
        # work.  FGFS_MODEL_HZ overrides for aircraft that need more.
        set -- "$@" "--prop:/sim/model-hz=${FGFS_MODEL_HZ:-60}"
        ;;
    *)
        echo "fgfs-run: unbekanntes Backend '$BACKEND' - siehe --list-backends" >&2
        exit 2 ;;
esac

if [ ! -x "$PREFIX/bin/fgfs" ]; then
    echo "fgfs-run: $PREFIX/bin/fgfs fehlt - ist das Paket fuer '$BACKEND' installiert?" >&2
    exit 3
fi

EGL_PLATFORM=wayland
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/display}
WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-wayland-0}
FGFS_SHM=${FGFS_SHM:-1}
export EGL_PLATFORM XDG_RUNTIME_DIR WAYLAND_DISPLAY FGFS_SHM

echo "fgfs-run: Backend $BACKEND ($PREFIX)"
exec "$PREFIX/bin/fgfs" --fg-root="$FGROOT" "$@"
