#!/bin/bash

function RequireNetwork()
{
  IsDaemonRunning && return

  echo "Starting network process (no daemon)"

  # tvprofile is declared in calling function
  tvprofile=("--profile-dir" "$TV_BASE_DIR")	# handle spaces in path properly
  RunNetworkProcess
}
  
function RequireWineServer()
{
  # Automatic start of wineserver fails sometimes when spawning from daemon, thus make sure it is running beforehand.
  # For QS, wineserver must run before profile creation (or be patched)
  if isQuickSupport; then
    LD_LIBRARY_PATH="$(getRPathW)" \
    "$TV_BIN_DIR/wine/bin/wineserver"
  else
    "$TV_BIN_DIR/wine/bin/wineserver"
  fi
}


function IsDaemonRunning()
{
  # Check if daemon is running - ignore for non-installed (TAR / TAR_QS)
  isInstalledTV || return 1

  exec &> /dev/null
  ps --no-heading -p $(cat "$TV_PIDFILE") | grep teamviewerd
}

function RunNetworkProcess()
{
  local subs
  local subPID
  local repeat=20
  
  # Start a network process
  trap Network_Signal SIGUSR1

  if isQuickSupport; then
    LD_LIBRARY_PATH="$(getRPathW)" \
    "$TV_BIN_DIR/teamviewerd" -n -f "${tvprofile[@]}" &		# tvprofile is declared in calling function
  else
    "$TV_BIN_DIR/teamviewerd" -n -f "${tvprofile[@]}" &		# tvprofile is declared in calling function
  fi
  subPID=$!

  # wait works, but could be entered too late
  until [ $repeat = 0 ]; do
    subs=$(jobs -r | wc -l)		# or: while subPID running
    
    if [ $subs = 0 ]; then		# network process quit (error or already running)
      echo "Network process already started (or error)"; break
    fi
    if [ -n "$TV_NET_STATE" ]; then	# signalled
      echo "Network process started ($subPID)"; break
    fi

    sleep 0.5
    let repeat-=1
  done
}

function Network_Signal()
{
  TV_NET_STATE='is_up'
}

function getRPath()
{
  echo "$TV_RTLIB_DIR"
}

function getRPathW()
{
  echo "$TV_RTLIB_DIR:$TV_WINELIB_DIR/wine:$TV_WINELIB_DIR"
}

function rtlExec()
{
  LD_LIBRARY_PATH="$(getRPath)" "$TV_BINLOADER" "$@"
}


# patch binaries to use shipped libraries/loader (patchelf)
function UpdateBinaries()
{
  isQuickSupport || return 0

  echo "Updating binaries..."
  
  local bmark="$TV_CFG_DIR/rtldir"
  local bpath=$(cat "$bmark" 2> /dev/null)
  if [ "$bpath" = "$(getRPath)" ]; then
    echo "Already up to date"
    return 0
  fi

  UpdateBinaryInterpreter "$TV_BIN_DIR/teamviewerd"		|| return 1
  UpdateBinaryInterpreter "$TV_BIN_DIR/TeamViewer_Desktop"	|| return 1
  UpdateBinaryInterpreter "$TV_BIN_DIR/wine/bin/wine"		|| return 1
  UpdateBinaryInterpreter "$TV_BIN_DIR/wine/bin/wineserver"	|| return 1

  UpdateBinaryRPathW "$TV_BIN_DIR/wine/drive_c/TeamViewer/tvwine.dll.so"	|| return 1
  UpdateBinaryRPathW "$TV_BIN_DIR/wine/bin/wine"				|| return 1
  UpdateBinaryRPathW "$TV_BIN_DIR/wine/lib/libwine.so.1.0"			|| return 1
  
  for lib in "$TV_BIN_DIR"/wine/lib/wine/*.dll.so ; do
    UpdateBinaryRPathW "$lib" || return 1
  done
  
  echo "$TV_RTLIB_DIR" > "$bmark" || return 1
  echo "Binaries patched"
}

function UpdateBinaryInterpreter()
{
    local bin="$1"
    local name=${bin##/*/}

    echo "Patching interpreter for $name"

    rtlExec "$TV_RTLIB_DIR/patchelf" --set-interpreter "$TV_BINLOADER" "$bin"
    UpdateBinaryRPath "$bin"
}

function UpdateBinaryRPath()
{
    local bin="$1"
    local name=${bin##/*/}

    echo "Patching rpath for $name"

    rtlExec "$TV_RTLIB_DIR/patchelf" --set-rpath "$(getRPath)" "$bin"
}

function UpdateBinaryRPathW()
{
    local bin="$1"
    local name=${bin##/*/}

    echo "Patching rpath for $name (w)"

    rtlExec "$TV_RTLIB_DIR/patchelf" --set-rpath "$(getRPathW)" "$bin"
}
