#!/bin/sh
# Aqueous init wrapper.
#
# Installed as /usr/bin/aqueous-init and run by Aqueous as its `-c` child:
#
#     exec aqueous -c '/usr/bin/aqueous-init'
#
# Aqueous now applies display configuration directly through wlroots before
# this child is launched and owns the outputd-compatible Unix socket itself.
# This wrapper seeds shell configuration, exports the live session environment,
# starts the graphical-session targets, then exits. Window-management policy
# runs inside the compositor.
set -u

# System-owned defaults copied into otherwise unconfigured user profiles.
AQUEOUS_SHARE_DIR="${AQUEOUS_SHARE_DIR:-/usr/share/aqueous}"

# Select the desktop before graphical-session.target starts shell units. The
# runtime snapshot keeps current-session shortcuts stable after a new selection.
# Declarative/non-Arch packages omit this helper and retain their own startup.
if [ "${AQUEOUS_NESTED:-0}" != 1 ]; then
    /usr/lib/aqueous/session-runtime.sh prepare-session || exit 1
fi

# Ghostty's client-side frame obscures the compositor-provided rounded border.
# Seed an undecorated default only for new Ghostty profiles; an existing config
# is user-owned and must never be changed by Aqueous.
GHOSTTY_USER_CFG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ghostty"
GHOSTTY_DEFAULTS="$AQUEOUS_SHARE_DIR/ghostty/config.ghostty"
if [ ! -e "$GHOSTTY_USER_CFG_DIR/config.ghostty" ] && [ -r "$GHOSTTY_DEFAULTS" ]; then
    mkdir -p "$GHOSTTY_USER_CFG_DIR"
    cp "$GHOSTTY_DEFAULTS" "$GHOSTTY_USER_CFG_DIR/config.ghostty"
    chmod 600 "$GHOSTTY_USER_CFG_DIR/config.ghostty"
fi

# Nested sessions inherit their endpoint directly and must not replace the
# real desktop's service environment.
[ "${AQUEOUS_NESTED:-0}" = 1 ] && exit 0

# Welcome has frozen the active shell for this login. Export the matching
# portal identity before UWSM finalization or any user-service activation.
session_runtime=${AQUEOUS_SESSION_RUNTIME:-/usr/lib/aqueous/session-runtime.sh}
portal_backend=xdg-desktop-portal-gtk.service
if [ -x "$session_runtime" ]; then
    selected_desktop=$("$session_runtime" portal-identity) && export XDG_CURRENT_DESKTOP="$selected_desktop"
    selected_backend=$("$session_runtime" portal-backend) && portal_backend=$selected_backend
fi

# Propagate an empty value after optional IPC failure to clear stale service
# manager endpoints from a previous compositor instance.
export AQUEOUS_SOCKET="${AQUEOUS_SOCKET:-}"

# Push the live Wayland and native XWayland environment into systemd --user
# and D-Bus so services and desktop-launched applications connect to this
# compositor. This must run here, not in aqueous-wm.sh, because
# WAYLAND_DISPLAY and DISPLAY are allocated only after Aqueous starts.
# The GPU-pin vars (MESA_VK_DEVICE_SELECT/__GLX_VENDOR_LIBRARY_NAME/DRI_PRIME/
# __NV_PRIME_RENDER_OFFLOAD) are set by Aqueous on this process's environment
# only on multi-GPU systems (empty on single-GPU). Forwarding them in the bare
# KEY form means the tools silently skip any that are unset, so this is inert on
# single-GPU machines and pins .desktop/systemd-launched apps to the same GPU
# the compositor renders on, closing the last launch path that could straddle
# two GPU stacks (the dual-GPU GObject toggle-ref crash).
display_var=""
[ -n "${DISPLAY:-}" ] && display_var="DISPLAY"

if command -v uwsm >/dev/null 2>&1 && [ -n "${UWSM_FINALIZE_SOCK:-}${WAYLAND_DISPLAY:-}" ]; then
    # uwsm owns the session lifecycle: `uwsm finalize` exports the (now-live)
    # Wayland env into the systemd --user + D-Bus activation environments AND
    # signals uwsm that the compositor is up, so it activates the real
    # graphical-session.target itself (satisfying xdg-desktop-portal's
    # Requisite=graphical-session.target) and pulls in xdg-desktop-autostart.target.
    # Crucially it re-exports the current WAYLAND_DISPLAY and native XWayland
    # DISPLAY on every start, so a compositor restart leaves no stale endpoint
    # pinned in the user manager.
    # The GPU-pin vars (set by Aqueous only on multi-GPU systems) are forwarded
    # in bare KEY form so uwsm silently skips any that are unset on single-GPU.
    # Cursor values affect subsequently activated applications. Environment
    # export cannot restyle the running compositor; use `aqueousctl cursor set`
    # for that live update.
    # shellcheck disable=SC2086
    uwsm finalize \
        WAYLAND_DISPLAY \
        AQUEOUS_SOCKET \
        $display_var \
        XDG_CURRENT_DESKTOP \
        XDG_SESSION_TYPE \
        XDG_RUNTIME_DIR \
        XCURSOR_THEME \
        XCURSOR_SIZE \
        MESA_VK_DEVICE_SELECT \
        __GLX_VENDOR_LIBRARY_NAME \
        DRI_PRIME \
        __NV_PRIME_RENDER_OFFLOAD 2>/dev/null || true
else
    # Fallback for sessions launched WITHOUT uwsm (e.g. a display manager that
    # execs aqueous-wm directly). Push the live session display environment
    # into systemd --user and D-Bus, then bring the graphical session up via
    # the aqueous-session.target wrapper (static
    # graphical-session.target has RefuseManualStart).
    if command -v dbus-update-activation-environment >/dev/null 2>&1; then
        # shellcheck disable=SC2086
        dbus-update-activation-environment --systemd \
            WAYLAND_DISPLAY \
            AQUEOUS_SOCKET \
            $display_var \
            XDG_CURRENT_DESKTOP \
            XDG_SESSION_TYPE=wayland \
            XDG_RUNTIME_DIR \
            XCURSOR_THEME \
            XCURSOR_SIZE \
            MESA_VK_DEVICE_SELECT \
            __GLX_VENDOR_LIBRARY_NAME \
            DRI_PRIME \
            __NV_PRIME_RENDER_OFFLOAD 2>/dev/null || true
    elif command -v systemctl >/dev/null 2>&1; then
        # Only import vars that are actually set, so older systemd versions never
        # warn on unset names (keeps the single-GPU case clean).
        optional_vars=""
        for v in XCURSOR_THEME XCURSOR_SIZE MESA_VK_DEVICE_SELECT __GLX_VENDOR_LIBRARY_NAME DRI_PRIME __NV_PRIME_RENDER_OFFLOAD; do
            eval "val=\${$v:-}"
            [ -n "$val" ] && optional_vars="$optional_vars $v"
        done
        # shellcheck disable=SC2086
        systemctl --user import-environment \
            WAYLAND_DISPLAY AQUEOUS_SOCKET XDG_CURRENT_DESKTOP XDG_SESSION_TYPE XDG_RUNTIME_DIR \
            $display_var $optional_vars \
            2>/dev/null || true
    fi

    systemctl --user start aqueous-session.target 2>/dev/null || true
    systemctl --user start xdg-desktop-autostart.target 2>/dev/null || true
fi

# Kick the portal in case it already failed earlier in the boot.
# reset-failed clears the start-limit so the restart actually runs.
systemctl --user reset-failed "$portal_backend" xdg-desktop-portal-aqueous.service 2>/dev/null || true
systemctl --user restart xdg-desktop-portal.service "$portal_backend" xdg-desktop-portal-aqueous.service 2>/dev/null || true

exit 0
