#!/usr/bin/env bash

if [[ $# -eq 0 ]] ; then

  echo "rootssh - invokes ssh and automatically configures tunel for remote ROOT session"
  echo ""
  echo "To start, just call:"
  echo ""
  echo "     [localhost] rootssh  user@remotehost"
  echo ""
  echo "And then in the ssh shell do:"
  echo ""
  echo "    [user@remotehost] source path/to/bin/thisroot.sh"
  echo "    [user@remotehost] root --web=server -e 'new TBrowser'"
  echo ""
  echo "Or just call in single line:"
  echo ""
  echo "    [localhost] rootssh  user@remotehost \"source path/to/bin/thisroot.sh; root --web=server -e 'new TBrowser'\""
  echo ""
  echo "ROOT automatically recognizes that it runs in special session (because of ROOT_LISTENER_SOCKET variable)"
  echo "and provides to this socket information to configure port forwarding and to start web windows automatically"
  echo ""
  echo "One can provide all supported by ssh arguments also to rootssh like '-E config.file' or '-Y'"
  echo "In addition, special rootssh arguments can be specified:"
  echo ""
  echo "    --port number - port number on local node used for ssh tunnel to remote"
  echo "    --browser <name> - name of web browser executable like firefox or chromium"
  echo ""
  echo " Thus one can call:"
  echo ""
  echo "     [localhost] rootssh --port 9753 --browser chromium -E config.file user@remotehost \"root --web 'new TBrowser'\""
  echo ""
  echo "Author: Sergey Linev, 2.12.2022"

elif [[ "$1" == "--as-listener--" ]] ; then

   # run listener, receive messages from ROOT messages
   # currently only win:$url messages are expected

   listener_socket=$2
   local_port=$3
   used_browser=$4

   flag=1
   NUM=1

   touch $listener_socket.log

   # on MacOS it is not possible to start netcat multiple times with same socket
   # therefore run it permanently and redirect output to log file
   nc -k -l -U $listener_socket >$listener_socket.log 2>/dev/null  &

   #remember processid to be able kill it
   nc_procid=$!

   # protect socket and log file from reading
   chmod 0700 $listener_socket $listener_socket.log

   # remove netcat listening on socket
   trap "kill -SIGINT $nc_procid >/dev/null 2>&1; rm -f $listener_socket.log" 0 1 2 3 6

   while [[ ($flag -ne 0) && (-f $listener_socket.log) ]] ; do

      line=$(sed "${NUM}q;d" $listener_socket.log)

      if [[ "${line}" == "" ]] ; then
         sleep 0.2
      elif [[ "${line:0:4}" == "win:" ]] ; then
         NUM=$((NUM+1))
         winurl=${line:4}
         # echo "Start window http://localhost:$local_port/$winurl"
         $used_browser "http://localhost:$local_port/$winurl"
      elif [[ "$line" == "stop" ]] ; then
         # echo "Get stop command $line"
         flag=0
      else
         echo "rootssh: got $line - not recoginzed, stop listener"
         flag=0
      fi
   done

else

   # main body

   listener_local="$(mktemp /tmp/root.XXXXXXXXX)"
   listener_remote="$(mktemp /tmp/root.XXXXXXXXX)"
   root_socket="$(mktemp /tmp/root.XXXXXXXXX)"

   rm -f $listener_local $listener_remote

   # analyze arguments

   localport=""
   browser=""
   ssh_destination=""
   ssh_command=""
   ssh_args=""

   ssh_array2=("-B -b -c -D -E -e -F -I -i -J -L -l -m -O -o -p -Q -R -S -W -w")

   while [ $# -gt 0 ] ; do
      if [[ "$1" == "--port"  ]] ; then
         localport=$2
         shift 2
      elif [[ "$1" == "--browser" ]] ; then
         browser=$2
         shift 2
      elif [[ " ${ssh_array2[*]} " =~ " $1 " ]]; then
         # arguments with extra option
         ssh_args+=" $1 $2"
         shift 2
      elif [[ "${1:0:1}" == "-" && "x$ssh_destination" == "x" ]]; then
         # any other arguments starting with "-"
         ssh_args+=" $1"
         shift
      elif [[ "x$ssh_destination" == "x" ]] ; then
         ssh_destination=$1
         shift
      else
         ssh_command+=" $1"
         shift
      fi
   done


   # List of potential local client browsers
   browsers=( xdg-open open chromium firefox )
   if [ -z "${browser}" ]; then
      for b in "${browsers[@]}"
      do
         # test if the browser is available.
         which ${b} 2>&1 >/dev/null
         if [ $? -eq 0 ]; then
            # The search was successful.
           browser=${b}
            break
         fi
      done
   fi

   if [ -z "${browser}" ]; then
       echo "No appropriate browser found; please use --browser option"
       exit 1
   fi

   if [[ "x$localport" == "x" ]] ; then
      probe="probing"
      localport=7777
      while [[ "x$probe" != "x" ]] ; do
         localport=$((7000 + $RANDOM%1000))
         probe=$(nc -zv localhost $localport 2>/dev/null)
      done
   fi

   echo "Use local port $localport for root_socket $root_socket redirection from $ssh_destination"

   # start listener process

   $0 --as-listener-- $listener_local $localport $browser &

   listener_processid=$!

   # by the exit kill listener and remove temporary files
   trap "kill -SIGINT $listener_processid > /dev/null 2>&1; rm -f $listener_local $listener_local.log $listener_remote $root_socket" 0 1 2 3 6

   # starting ssh

   if [[ "x$ssh_command" == "x" ]] ; then
      ssh_command="\$SHELL"
   fi

   ssh -t -R $listener_remote:$listener_local -L $localport:$root_socket $ssh_destination $ssh_args \
   "chmod 0700 $listener_remote; export ROOT_WEBDISPLAY=server; export ROOT_LISTENER_SOCKET=$listener_remote; export ROOT_WEBGUI_SOCKET=$root_socket; $ssh_command; rm -f $listener_remote $root_socket"

fi