#!/bin/sh
launcher_dir=$(dirname "$0")
if [ -x "${launcher_dir}/MatrixCode" ]; then
  binary="${launcher_dir}/MatrixCode"
else
  binary="${launcher_dir}/../../bin/MatrixCode"
fi

child_pid=
pending_signal=
pending_exit_status=

forward_signal() {
  signal_name=$1
  exit_status=$2
  if [ -z "${child_pid}" ]; then
    pending_signal=${signal_name}
    pending_exit_status=${exit_status}
    return
  fi
  trap - HUP INT TERM
  if ! kill "-${signal_name}" "-${child_pid}" 2>/dev/null; then
    kill "-${signal_name}" "${child_pid}" 2>/dev/null || true
    kill "-${signal_name}" "-${child_pid}" 2>/dev/null || true
  fi
  wait "${child_pid}" 2>/dev/null || true
  exit "${exit_status}"
}

trap 'forward_signal HUP 129' HUP
trap 'forward_signal INT 130' INT
trap 'forward_signal TERM 143' TERM

software_fallback=false
while :; do
  # The dedicated session lets lifecycle signals reach Qt helper processes too.
  if [ "${software_fallback}" = true ]; then
    setsid env --default-signal=HUP,INT,TERM "${binary}" --software "$@" &
  else
    setsid env --default-signal=HUP,INT,TERM "${binary}" "$@" &
  fi
  child_pid=$!
  if [ -n "${pending_signal}" ]; then
    forward_signal "${pending_signal}" "${pending_exit_status}"
  fi

  wait "${child_pid}"
  status=$?
  child_pid=
  if [ -n "${pending_signal}" ]; then
    trap - HUP INT TERM
    exit "${pending_exit_status}"
  fi
  if [ "${status}" -eq 75 ] && [ "${software_fallback}" = false ]; then
    software_fallback=true
    continue
  fi

  trap - HUP INT TERM
  exit "${status}"
done
