#!/bin/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

   while [ $flag -ne 0 ] ; do

      line="$(netcat -l -U $listener_socket)"

      if [[ "${line:0:5}" == "http:" ]] ; then
         remoteport=${line:5}
         # echo "Want to map remote port $localport:localhost:$remoteport"
      elif [[ "${line:0:7}" == "socket:" ]] ; then
         remotesocket=${line:7}
         #  echo "Remote socket was created $remotesocket"
      elif [[ "${line:0:4}" == "win:" ]] ; then
         winurl=${line:4}
         # echo "Start window http://localhost:$local_port/$winurl"
         $used_browser "http://localhost:$local_port/$winurl"
      elif [[ "$line" == "stop" ]] ; then
         flag=0
      else
         echo "Command not recognized $line - stop"
         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="xdg-open"
   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

   if [[ "x$localport" == "x" ]] ; then
      probe="probing"
      localport=7777
      while [[ "x$probe" != "x" ]] ; do
         localport=$((7000 + $RANDOM%1000))
         probe=$(netcat -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=$!

   # start 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_LISTENER_SOCKET=$listener_remote; export ROOT_WEBGUI_SOCKET=$root_socket; $ssh_command; rm -f $listener_remote $root_socket"

   # try to stop listener with "stop" message

   echo "stop" | netcat -U $listener_local -q 1 >/dev/null 2>&1

   # Kill listener process

   kill -9 $listener_processid > /dev/null 2>&1

   # Remove temporary files

   rm -f $listener_local $listener_remote
fi
