#!/bin/bash
DRY_RUN=0
function printHelp {
  echo "Utility to run games and applications in separate X on discrete Nvidia graphic card"
  echo "Usage: "
  echo "nvidia-xrun [<options>] [<app>]"
  echo "Options: "
  echo "  -d    Dry run - prints the final command but does not execute it"
}

function execute {
  if [ ${DRY_RUN} -eq 1 ]
    then
    echo ">>Dry run. Command: $*"
  else
    eval $*
  fi
}


if [[ $EUID -eq 0 ]]; then
   echo "This script must not be run as root" >&2
   exit 1
fi

if [ "$1" == "-d" ]
  then
    DRY_RUN=1
    shift 1
fi

# calculate current VT
LVT=`fgconsole`

# calculate first usable display
XNUM="-1"
SOCK="something"
while [ ! -z "$SOCK" ] 
do
  XNUM=$(( $XNUM + 1 ))
  SOCK=$(ls -A -1 /tmp/.X11-unix | grep "X$XNUM" )
done

NEWDISP=":$XNUM"

if [ ! -z "$*" ] # generate exec line if arguments are given
then 
  # test if executable exists in path
  if [ -x "$(which $1 2> /dev/null)" ]
  then
    # generate exec line
    EXECL="$(which $1)"
  # test if executable exists on disk
  elif [ -e "$(realpath "$1")" ]
  then
    # generate exec line
    EXECL="$(realpath "$1")"
  else
    echo "$1: No such executable!"
    exit 1
  fi
  shift 1
  EXECL="$EXECL $*"
else # prepare to start new X sessions if no arguments passed
  EXECL=""
fi

EXECL="/etc/X11/xinit/nvidia-xinitrc $EXECL"

COMMAND="xinit $EXECL -- $NEWDISP vt$LVT -nolisten tcp -br -config nvidia-xorg.conf -configdir nvidia-xorg.conf.d"

# --------- TURNING ON GPU -----------
echo 'Waking up nvidia GPU'
if ! [ -f /proc/acpi/bbswitch ] 
then
  execute "sudo modprobe bbswitch"
fi
execute "sudo tee /proc/acpi/bbswitch <<<ON"

# ---------- LOADING MODULES ----------
echo 'Loading nvidia module'
execute "sudo modprobe nvidia"

echo 'Loading nvidia_modeset module'
execute "sudo modprobe nvidia_modeset"

echo 'Loading nvidia_drm module'
execute "sudo modprobe nvidia_drm"

# ---------- EXECUTING COMMAND --------
execute ${COMMAND}

# ---------- UNLOADING MODULES --------
echo 'Unloading nvidia_drm module'
execute "sudo rmmod nvidia_drm"

echo 'Unloading nvidia_modeset module'
execute "sudo rmmod nvidia_modeset"

echo 'Unloading nvidia module'
execute "sudo rmmod nvidia"

# --------- TURNING OFF GPU ----------
if [ -f /proc/acpi/bbswitch ] 
then
  echo 'Turning off nvidia GPU'
  execute "sudo tee /proc/acpi/bbswitch <<<OFF"

  echo -n 'Current state of nvidia GPU: '
  execute "cat /proc/acpi/bbswitch"
else
  echo "Bbswitch kernel module not loaded."
fi
