#!/bin/bash

set -euo pipefail

# The domain name of the go module proxy inside the VPN of the host you're SSH-ing into
# TODO: When ticket for a2z hostname finishes, I'll change this
TWITCH_GOPROXY=${TWITCH_GOPROXY:-goproxy.twitch.a2z.com}
# The host you SSH into to make your module proxy tunnel
GOPROXY_JUMPBOX=${GOPROXY_JUMPBOX:-jumpbox}
# The SSH control file that we send shutdown signals on (also helps with pgrep to kill outstanding tunnels)
GOPROXY_SSH_FILE="${HOME}/.tgoproxy.ssh.sock"
# If set to non empty, we will use the HTTPS endpoint for the go proxy rather than the HTTP endpoint
GOPROXY_HTTPS=${GOPROXY_HTTPS:-}
# The local port we connect to the tgoproxy on
LOCAL_GOPROXY_PORT=${LOCAL_GOPROXY_PORT-8123}
# The hostname we connect to locally for our go proxy.  If we're using HTTPS, this should be a name that resolves a TLS
# certificate
LOCAL_GOPROXY_HOSTNAME=${LOCAL_GOPROXY_HOSTNAME-local.goproxy.twitch.a2z.com}

# The user you SSH as
function bastion_ssh_user() {
    BASTION_SSH_USER=${BASTION_SSH_USER:-"$(teleport-bastion config ldap_username)"}
    echo -n ${BASTION_SSH_USER}
}

function proxy_remote_port() {
  if [[ ! -z "${GOPROXY_HTTPS-}" ]]; then
    echo "443"
    return
  fi
  echo "80"
}

function proxy_remote_protocol() {
  if [[ ! -z "${GOPROXY_HTTPS-}" ]]; then
    echo "https"
    return
  fi
  echo "http"
}

function root__enable() {
  if [[ "${1-}" == "help" ]]; then
    echo "Start SSH tunnel to tgoproxy"
    exit 0
  fi
  if root__status; then
    echo "proxy already enabled"
    return
  fi
  # Note.  You also need to be logged in (not just have the tunnel running)
  teleport-bastion status
  # Note: You must be in the ghe-users LDAP group
  TC=golang-proxy-prod ssh -fTNMS ${GOPROXY_SSH_FILE} -L ${LOCAL_GOPROXY_PORT}:${TWITCH_GOPROXY}:$(proxy_remote_port) $(bastion_ssh_user)@${GOPROXY_JUMPBOX}
}

function root__status() {
  if [[ "${1-}" == "help" ]]; then
    echo "Check status to tgoproxy tunnel"
    exit 0
  fi
  ssh -S ${GOPROXY_SSH_FILE} -TO check hostname
}

function root__test() {
  if [[ "${1-}" == "help" ]]; then
    echo "Execute a simple command to see if you actually have access to the proxy"
    exit 0
    fi
  if [[ -z "${GOPROXY-}" ]]; then
    echo "GOPROXY environment variable not set.  Please set this variable via \"export\""
    return
  fi
  curl $(proxy_remote_protocol)://${LOCAL_GOPROXY_HOSTNAME}:${LOCAL_GOPROXY_PORT}
  echo
  curl ${GOPROXY}
  echo
  echo "Running a sample go get to verify access"
  GO111MODULE=on go get -u -v code.justin.tv/hygienic/exampledep@v0.0.1
}

function root__disable() {
  if [[ "${1-}" == "help" ]]; then
    echo "Disable tgoproxy tunnel"
    exit 0
  fi
  # This should be enough, but sometimes SSH sessions linger.  So we kill them with pgrep below
  ssh -S ${GOPROXY_SSH_FILE} -TO exit hostname || true
  rm -f ${GOPROXY_SSH_FILE}
  pgrep -f "ssh.*${GOPROXY_SSH_FILE}" | xargs kill
}

function tgoproxy_export_env() {
  TORUN=$(root__export || true)
  eval "${TORUN}"
  if echo ${TORUN} | grep "unable to find" > /dev/null ; then
    return 1
  fi
}

AS_EXECUTED=${0-tgoproxy}
function root__export() {
  if [[ "${1-}" == "help" ]]; then
    echo "Lets you export the GOPROXY.  Use with export:    export GOPROXY=\$(${AS_EXECUTED} export)"
    exit 0
  fi
  # Proxy explicitly set
  if [[ ! -z "${GOPROXY-}" ]]; then
    echo -n ${GOPROXY}
    return
  fi
  # Purposely sending proxy via SSH
  if [[ -e "${GOPROXY_SSH_FILE}" ]]; then
    echo -n "$(proxy_remote_protocol)://${LOCAL_GOPROXY_HOSTNAME}:${LOCAL_GOPROXY_PORT}"
    return
  fi
  return 1
}

# Process a help flag for every subcommand
function process_help() {
  prefix=$1
  shift
  if [[ "${1-}" == "help" ]]; then
    echo "Prints each command and help"
    exit 0
  fi

  compgen -A function | grep $prefix | sort | while read -r line; do
    echo
    echo "  ${line:${#prefix}}"
    echo "    $($line help)"
  done
}

# This is the core to our __ expansion magic
function process_build() {
  prefix=$1
  shift
  T="$prefix${1-}"
  if declare -F "$T" >/dev/null ; then
    func="$prefix${1}"
    shift; # pop $1
    "$func" "$@"    # invoke our named function w/ all remaining arguments
  else
    echo "Undefined subcommand ${1-}"
    process_help $prefix
    exit 1
  fi
}

process_build root__ $@
