#!/usr/bin/env bash

set +e

function echo_stderr() {
    echo "$@" >&2
}

function check_port() {
    local val="$1"

    if (( val < 1 || val > 65000 )); then
      echo_stderr "The port $val is not valid"
	    help
	  fi
}

function find_preload {
  if [[ -n "${GLOBUS_STREAMS_CLIENT_LIB}" ]]; then
      echo "${GLOBUS_STREAMS_CLIENT_LIB}"
      return 0
  fi

  if ldconfig -p 2>/dev/null | grep -q globus_streams_client; then
      echo "libglobus_streams_client.so.0"
      return 0
  fi

  arch=$(uname -m)
  candidates=(
      "/usr/lib/${arch}-linux-gnu/libglobus_streams_client.so.0"
      "/usr/lib64/${arch}-linux-gnu/libglobus_steams_client.so.0"
      "/usr/lib64/libglobus_streams_client.so.0"
      "/usr/lib/libglobus_streams_client.so.0"
  )
  for c in ${candidates[@]}; do
    if [[ -f ${c} ]]; then
      echo ${c}
      return 0
    fi
  done

  return 1
}

function is_uuid {
    local s="$1"
    [[ $s =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ ]]
}

function check_tunnel_id {
  tunnel_id=${1}

  is_uuid ${tunnel_id}
  if [[ $? -ne 0 ]]; then
      echo_stderr "The value '${tunnel_id}' does not appear to be a tunnel ID."
      return 1
  fi

  local lankey_env_name="GLOBUS_STREAMS_LANKEY_$tunnel_id"
  local contact_env_name="GLOBUS_STREAMS_CONTACT_$tunnel_id"

  if [[ -v "$lankey_env_name" && -v "$contact_env_name" ]]; then
    echo_stderr "Using the environment variables for information"
    return 0
  fi

  if [[ -n "${GLOBUS_STREAMS_SOCKET_CONFIG_DIR}" ]]; then
      conf_file="${GLOBUS_STREAMS_SOCKET_CONFIG_DIR}/${tunnel_id}.conf"
  else
      conf_file="${HOME}/.globus/streams/${tunnel_id}.conf"
  fi

  if [[ -f ${conf_file} ]]; then
      return 0
  fi
  return 1
}

function help {
    echo_stderr "$0 [OPTIONS] <tunnel id> <command> ..."
    echo_stderr ""
    echo_stderr "Options:"
    echo_stderr "   -p <server port>         Running an app listener on this port"
    echo_stderr "   -d                       Show debug output"
    echo_stderr "   -l <file name>           Send debug output to this file "
    echo_stderr "This will setup the environment that a program will run in for use with Globus Streams. It will find the Tunnel intercept library and set LD_PRELOAD to its location. This will allow users to seamlessly interact with Globus Streams."
    echo_stderr ""
    echo_stderr "Before using this you must initialize the environment with the `globus-tunnel environment initialize` command."
    echo_stderr ""
    echo_stderr "If running a program with a server socket you can use the -p option to tell this script what port your program will listen on and this will set the environment variable GLOBUS_STREAMS_INTERCEPT_PORT_<port>=<tunnel id>."
    exit 1
}


SERVER_PORT=
DEBUG=
DEBUG_LOGFILE=
while getopts "hp:dl:" opt; do
  case $opt in
    p)
      SERVER_PORT=$OPTARG
      check_port $SERVER_PORT
      ;;
    d)
      DEBUG="ALL"
      ;;
    l)
      DEBUG_LOGFILE=$OPTARG
      ;;
    *)
      help
      ;;
  esac
done
shift $((OPTIND - 1))

if [[ $# -lt 2 ]]; then
    help
fi

if [[ -n ${DEBUG_LOGFILE} ]]; then
    export GLOBUS_AWAI_DEBUG=ALL,${DEBUG_LOGFILE}
elif [[ -n ${DEBUG} ]]; then
    export GLOBUS_AWAI_DEBUG=ALL
fi

LD_PRELOAD=$(find_preload)
if [[ $? -ne 0 ]]; then
  echo_stderr "The tunnel intercept library was not found."
  exit 1
fi
echo_stderr "Using the preload library ${LD_PRELOAD}"

TUNNEL_ID=${1}
check_tunnel_id ${TUNNEL_ID}
if [[ $? -ne 0 ]]; then
  echo_stderr "The tunnel configuration file for the tunnel '${TUNNEL_ID}' was not found. The environment may not be configured properly of you may have not passed in the correct tunnel ID."
  exit 1
fi
shift

if [[ -n "${SERVER_PORT}" ]]; then
    echo_stderr "Using the server port $SERVER_PORT"
    export GLOBUS_STREAMS_INTERCEPT_PORT_${SERVER_PORT}=${TUNNEL_ID}
    key="GLOBUS_STREAMS_INTERCEPT_PORT_${SERVER_PORT}"
fi

export LD_PRELOAD
export GLOBUS_STREAMS_TUNNELS=${TUNNEL_ID}

echo_stderr "Running: ${@}"
exec "${@}"
