#!/usr/bin/env bash
# Run Nebula from an extracted AppImage folder with safe LD/XDG paths and Linux flags.
# This repo can end up with either:
# - nebula-appdir/squashfs-root/nebula (common after copying squashfs-root into nebula-appdir)
# - nebula-appdir/nebula (if you copied the extracted contents directly into nebula-appdir)
#
# PORTABLE MODE: User data (cookies, history, bookmarks) is stored in usr/data/ alongside the app.
# This keeps all data self-contained and portable on Linux.
set -euo pipefail

SELF_DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 && pwd)"

if [ -x "$SELF_DIR/nebula-appdir/nebula" ]; then
	APPROOT="$SELF_DIR/nebula-appdir"
	BIN="$APPROOT/nebula"
elif [ -x "$SELF_DIR/squashfs-root/nebula" ]; then
	APPROOT="$SELF_DIR/squashfs-root"
	BIN="$APPROOT/nebula"
elif [ -x "$SELF_DIR/nebula" ]; then
	APPROOT="$SELF_DIR"
	BIN="$APPROOT/nebula"
else
	echo "Nebula binary not found. Expected either:"
	echo "- $SELF_DIR/nebula-appdir/nebula"
	echo "- $SELF_DIR/squashfs-root/nebula"
	echo "- $SELF_DIR/nebula"
	exit 1
fi

# --- PORTABLE DATA CONFIGURATION ---
# Store user data (cookies, history, bookmarks, etc.) in a local folder
# Data is stored with secure permissions (700 for dirs, 600 for files)
PORTABLE_DATA_DIR="$SELF_DIR/usr/data"
export NEBULA_PORTABLE=1
export NEBULA_PORTABLE_PATH="$PORTABLE_DATA_DIR"

# Create portable data directory with secure permissions if it doesn't exist
if [ ! -d "$PORTABLE_DATA_DIR" ]; then
	mkdir -p "$PORTABLE_DATA_DIR"
	chmod 700 "$PORTABLE_DATA_DIR"
fi

export LD_LIBRARY_PATH="$APPROOT/usr/lib:${LD_LIBRARY_PATH:-}"
export XDG_DATA_DIRS="$APPROOT/usr/share:${XDG_DATA_DIRS:-/usr/share}"

# =============================================================================
# STEAM INPUT CONFIGURATION - Always set these to prevent controller emulation
# =============================================================================
# These variables tell Steam's input layer that this app handles controller
# input natively and should NOT have mouse/keyboard emulation applied.
# Set unconditionally since Software apps may not receive Steam env vars.

# Disable Steam's virtual gamepad layer - CRITICAL for native controller support
export SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD=0
export STEAM_INPUT_ENABLE_VIRTUAL_GAMEPAD=0

# Allow raw gamepad access
export SDL_GAMECONTROLLER_IGNORE_DEVICES=""

# Allow background gamepad events (useful when app doesn't have focus)
export SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS=1

# Hint to SDL that we're using gamepads natively
export SDL_GAMECONTROLLERCONFIG="${SDL_GAMECONTROLLERCONFIG:-}"

# Steam can inject its overlay via LD_PRELOAD (gameoverlayrenderer.so).
# In some setups this breaks Chromium/Electron gamepad input. When we detect
# a Steam-launched session, strip the overlay preload but keep other entries.
# Also configure additional Steam-specific settings.
if [ -n "${SteamAppId:-}" ] || [ -n "${STEAM_APP_ID:-}" ] || [ -n "${STEAM_COMPAT_CLIENT_INSTALL_PATH:-}" ] || [ -n "${STEAM_COMPAT_DATA_PATH:-}" ]; then
	# Enable Big Picture Mode for controller-friendly UI when launched from Steam
	export NEBULA_BIG_PICTURE="${NEBULA_BIG_PICTURE:-1}"
	
	# Enable GPU acceleration on Linux
	export NEBULA_GPU_ALLOW_LINUX=1
	
	if [ -n "${LD_PRELOAD:-}" ]; then
		CLEANED_LD_PRELOAD=""
		IFS=':' read -r -a _preload_parts <<< "$LD_PRELOAD"
		for _p in "${_preload_parts[@]}"; do
			[ -z "$_p" ] && continue
			case "$_p" in
				*gameoverlayrenderer.so*)
					;;
				*)
					if [ -z "$CLEANED_LD_PRELOAD" ]; then
						CLEANED_LD_PRELOAD="$_p"
					else
						CLEANED_LD_PRELOAD="$CLEANED_LD_PRELOAD:$_p"
					fi
					;;
			esac
		done
		if [ -z "$CLEANED_LD_PRELOAD" ]; then
			unset LD_PRELOAD
		else
			export LD_PRELOAD="$CLEANED_LD_PRELOAD"
		fi
	fi
fi

GPU_ARGS=()

# Optional GPU tuning profiles strike a balance between enabling hardware decode
# and keeping the launcher safe on systems with fragile Mesa/VA-API stacks.
# Default to enabling GPU tweaks on Linux unless explicitly disabled.
export NEBULA_GPU_PROFILE="${NEBULA_GPU_PROFILE:-}"
GPU_GL_MODE="${NEBULA_GPU_GL:-}"
export NEBULA_GPU_TWEAKS="${NEBULA_GPU_TWEAKS:-1}"

if [ "${NEBULA_GPU_TWEAKS}" = "1" ] && [ -z "$NEBULA_GPU_PROFILE" ]; then
	export NEBULA_GPU_PROFILE=vaapi
fi

case "$NEBULA_GPU_PROFILE" in
	vaapi)
		GPU_ARGS+=(--ignore-gpu-blocklist)
		GPU_ARGS+=(--enable-features=VaapiVideoDecoder,VaapiVideoEncoder,CanvasOopRasterization,UseSkiaRenderer,VaapiVideoDecoderLinuxGL,VaapiVideoDecoderLinuxZeroCopyGL)
		GPU_ARGS+=(--enable-zero-copy)
		GPU_ARGS+=(--enable-gpu-rasterization)
		GPU_ARGS+=(--enable-accelerated-video-decode)
		GPU_ARGS+=(--enable-native-gpu-memory-buffers)
		if [ -z "${LIBVA_DRIVER_NAME:-}" ]; then
			export LIBVA_DRIVER_NAME=radeonsi
		fi
		;;
	angle)
		GPU_ARGS+=(--ignore-gpu-blocklist)
		GPU_ARGS+=(--enable-features=VaapiVideoDecoder,VaapiVideoEncoder,CanvasOopRasterization,UseSkiaRenderer,VaapiVideoDecoderLinuxGL)
		GPU_ARGS+=(--enable-zero-copy)
		GPU_ARGS+=(--enable-gpu-rasterization)
		GPU_ARGS+=(--enable-native-gpu-memory-buffers)
		GPU_ARGS+=(--enable-accelerated-video-decode)
		if [ -z "${LIBVA_DRIVER_NAME:-}" ]; then
			export LIBVA_DRIVER_NAME=radeonsi
		fi
		if [ -z "${AMD_VULKAN_ICD:-}" ]; then
			export AMD_VULKAN_ICD=RADV
		fi
		;;
	amd-handheld)
		GPU_ARGS+=(--ignore-gpu-blocklist)
		GPU_ARGS+=(--use-angle=vulkan)
		AMD_HANDHELD_FEATURES="VaapiVideoDecoder,VaapiVideoEncoder,CanvasOopRasterization,UseSkiaRenderer,VaapiVideoDecoderLinuxGL,VaapiVideoDecoderLinuxZeroCopyGL"
		if [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
			AMD_HANDHELD_FEATURES="UseOzonePlatform,WaylandWindowDecorations,${AMD_HANDHELD_FEATURES}"
			GPU_ARGS+=(--ozone-platform-hint=auto)
			GPU_ARGS+=(--ozone-platform=wayland)
		fi
		GPU_ARGS+=(--enable-features="$AMD_HANDHELD_FEATURES")
		GPU_ARGS+=(--enable-zero-copy)
		GPU_ARGS+=(--enable-gpu-rasterization)
		if [ -z "${LIBVA_DRIVER_NAME:-}" ]; then
			export LIBVA_DRIVER_NAME=radeonsi
		fi
		if [ -z "${MESA_VK_WSI_PRESENT_MODE:-}" ]; then
			export MESA_VK_WSI_PRESENT_MODE=mailbox
		fi
		;;
	software)
		GPU_ARGS+=(--disable-gpu)
		;;
	"")
		;;
	*)
		echo "Warning: Unknown NEBULA_GPU_PROFILE '$NEBULA_GPU_PROFILE'" >&2
		;;
esac

if [ -n "$GPU_GL_MODE" ]; then
	# Map common GL mode names to Electron-compatible values
	case "$GPU_GL_MODE" in
		egl|egl-angle) GPU_GL_MODE="angle" ;;
		desktop) GPU_GL_MODE="desktop" ;;
	esac
	GPU_ARGS+=(--use-gl="$GPU_GL_MODE")
fi

if [ -n "${NEBULA_GPU_EXTRA_ARGS:-}" ]; then
	# shellcheck disable=SC2086 # word splitting is intentional for custom flag tokens
	read -r -a _nebula_gpu_extra <<< "${NEBULA_GPU_EXTRA_ARGS}"
	GPU_ARGS+=("${_nebula_gpu_extra[@]}")
fi

exec "$BIN" --no-sandbox "${GPU_ARGS[@]}" "$@"
