#!/bin/bash

## Copyright (C) 2024 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## Pipe all logs to the journal or to /dev/null. Prevents them from being seen
## by the user and makes them more accessible if needed.
## Taken from https://stackoverflow.com/a/54415774/19474638
## For debugging, uncomment this line and comment out the next line.
#exec > >(systemd-cat --identifier=sysmaint-session-wayland) 2>&1
exec >/dev/null 2>&1

# shellcheck source=../../../../helper-scripts/usr/libexec/helper-scripts/light_sleep.bsh
source /usr/libexec/helper-scripts/light_sleep.bsh

# shellcheck source=../../../../helper-scripts/usr/libexec/helper-scripts/has.sh
source /usr/libexec/helper-scripts/has.sh

# shellcheck source=../../../../helper-scripts/usr/libexec/helper-scripts/try_wait_for_audio_ready.bsh
source /usr/libexec/helper-scripts/try_wait_for_audio_ready.bsh

# shellcheck source=./sysmaint-session-shared
source /usr/libexec/user-sysmaint-split/sysmaint-session-shared

## Terminate any Wayland compositors that are already running in our user
## account. Necessary to allow login to work after 'sudo systemctl restart
## greetd' is run.
for old_wl_sock in "/run/user/$(id -u)"/wayland-*; do
  if ! [ -S "${old_wl_sock}" ]; then
    continue
  fi
  old_wl_pid="$(/usr/libexec/helper-scripts/query-sock-pid "${old_wl_sock}")" \
    || continue
  kill "${old_wl_pid}" || true
  old_wl_kill_timeout=5
  while (( old_wl_kill_timeout != 0 )); do
    light_sleep 1
    if ! [ -d "/proc/${old_wl_pid}" ]; then
      break
    fi
    (( old_wl_kill_timeout-- )) || true
  done
  if (( old_wl_kill_timeout == 0 )); then
    printf '%s\n' "WARNING: Could not kill old Wayland compositor with pid '${old_wl_pid}'!"
  fi
done

if [ "$PROFILE_SCRIPTS_WERE_SOURCED" != 'yes' ]; then
   source /etc/profile ## this pulls in /etc/profile.d as well
fi

export XDG_CURRENT_DESKTOP='sysmaint-session-wayland'
export QT_QPA_PLATFORMTHEME='lxqt'
export XDG_SESSION_TYPE='wayland'

window_manager_list=(
   '/usr/bin/labwc'
   # Add other window managers here later
)
window_manager_arg_list=(
  # Enabled merged config for labwc, needed for the keyboard layout to be
  # properly handled
  '-m'
)
selected_window_manager=''
for idx in "${!window_manager_list[@]}"; do
   if [ -e "${window_manager_list[idx]}" ]; then
     selected_window_manager="${window_manager_list[idx]}"
     selected_window_manager_args="${window_manager_arg_list[idx]}"
     break
   fi
done

sysmaint_app_list=(
   '/usr/bin/sysmaint-panel'
   '/usr/bin/x-terminal-emulator'
)
selected_sysmaint_app=''
for sysmaint_app in "${sysmaint_app_list[@]}"; do
   if [ -e "${sysmaint_app}" ]; then
      selected_sysmaint_app="${sysmaint_app}"
      break
   fi
done

system_tray_list=(
   '/usr/bin/waybar'
)
system_tray_arg_list=(
   ''
)

for (( idx = 0; idx < ${#system_tray_list[@]}; idx++ )); do
   if [ -e "${system_tray_list[idx]}" ]; then
      selected_system_tray="${system_tray_list[idx]}"
      selected_system_tray_args="${system_tray_arg_list[idx]}"
      break
   fi
done

if [ -z "${selected_window_manager}" ]; then
   printf "%s\n" "$0: ERROR: Could not find a supported window manager!" >&2
   exit 1
fi
if [ -z "${selected_sysmaint_app}" ]; then
   printf "%s\n" "$0: ERROR: Could not find a supported sysmaint app!" >&2
   exit 1
fi

dbus-update-activation-environment --systemd --all

write_sysmaint_account_specific_config_once

do_once_dir="$HOME/.local/share/kicksecure/do_once"
mkdir --parents -- "${do_once_dir}"

if has pactl; then
   try_wait_for_audio_ready

   ## Audio may start muted by default. Waybar provides no good way to unmute
   ## it, so let's unmute it for the user. If they want to mute the speakers,
   ## they can set the volume to 0%.
   timeout --kill-after="1" "1" pactl set-sink-mute @DEFAULT_SINK@ false || true

   ## When not running under a VM, try to set the speaker volume to a safe
   ## default (50%). Only do this once. If the attempt fails for whatever
   ## reason, or the use of a VM is detected, skip setting the speaker volume
   ## and don't try to set it again in the future.
   ## Also in
   ## desktop-config-dist/usr/libexec/desktop-config-dist/start-lxqt-session.
   if ! [ -f "${do_once_dir}/set_safe_speaker_volume" ]; then
      touch -- "${do_once_dir}/set_safe_speaker_volume"
      if [ "$(systemd-detect-virt 2>/dev/null || true)" = 'none' ]; then
          timeout --kill-after="1" "1" pactl set-sink-volume @DEFAULT_SINK@ 50% || true
      fi
   fi
fi

# shellcheck disable=SC2086
"${selected_window_manager}" ${selected_window_manager_args} &
## Needed to prevent window ordering and initialization problems
## WARNING: `light_sleep 1` IS NOT SUFFICIENT HERE. On machines with physical
## graphics hardware, the compositor takes more time than expected to
## initialize. Other applications will try to start before the Wayland
## compositor is fully initialized if `light_sleep 1` is used, crashing the
## compositor in the process.
##
## On an i5-13500H system, `light_sleep 2` is sufficient to allow the
## compositor to fully initialize before other applications are run. To allow
## some leeway for slower systems, `light_sleep 3` is what we use here for
## now.
light_sleep 3

## labwc updates systemd's activation environment with environment variables
## like $DISPLAY, $WAYLAND_DISPLAY, and $LABWC_PID. Import any variables from
## systemd that are not already set in our environment.
##
## From the systemctl manpage:
##
##     If no special characters or whitespace is present in the variable
##     values, no escaping is performed, and the assignments have the form
##     "VARIABLE=value". If whitespace or characters which have special
##     meaning to the shell are present, dollar-single-quote escaping is used,
##     and assignments have the form "VARIABLE=$'value'".
##
## Thus we can safely process the output of 'systemctl show-environment'
## line-by-line and import variables using 'eval'.
while read -r systemd_env_line; do
   systemd_env_var_name="$(cut -z -d'=' -f1 <<< "${systemd_env_line}")"
   if ! [ -v "${systemd_env_var_name}" ]; then
      eval "${systemd_env_line}"
      export "${systemd_env_var_name}"
   fi
done < <(systemctl --user show-environment)

if [ -n "${selected_system_tray}" ]; then
   # shellcheck disable=SC2086
   "${selected_system_tray}" ${selected_system_tray_args} &
fi

"${selected_sysmaint_app}" &
sysmaint_app_pid="$!"

start_user_background_services

leaprun signal-wayland-session-started

wait "${sysmaint_app_pid}"
