#!/bin/bash
#
# Starts up a shell running under the security agent.
#
# Specifically:
#
# 1. Fetches the binaries needed to set up the security environment.  If it
# can't fetch fresh binaries, it issues a warning but proceeds with existing
# binaries, if any.
#
# 2. Starts a shell under the agent, optionally fetching a remote blessing if
# the principal is missing.
#
# Uses ~/.vbash to store its files, including binaries and the principal.
#
# Usage:
#
# # Builds and fetches binaries from local repository
# ./vbash
#
# # Gets binaries from local filesystem
# ./vbash /path/to/binaries
#
# # Gets binaries from HTTP server
# ./vbash http://host/path
#
# Limitations:
# Tested on goobuntu and OS X 10.9.5.

set -e

readonly BIN_PACKAGES=(v.io/core/veyron/tools/principal v.io/core/veyron/security/agent/agentd)
BIN_NAMES=(${BIN_PACKAGES[@]})
for (( i=0; i<${#BIN_PACKAGES[@]}; i++ )); do
  BIN_NAMES[$i]=$(basename "${BIN_PACKAGES[$i]}")
done

# TODO(caprita): share copy_binaries and get_binaries with nminstall.

###############################################################################
# Copies one binary from source to destination.
# Arguments:
#   name of the binary
#   source dir of binary
#   destination dir of binary
# Returns:
#   None
###############################################################################
copy_binary() {
  local -r BIN_NAME="$1"
  local -r BIN_SRC_DIR="$2"
  local -r BIN_DEST_DIR="$3"
  local -r SOURCE="${BIN_SRC_DIR}/${BIN_NAME}"
  if [[ -x "${SOURCE}" ]]; then
    local -r DESTINATION="${BIN_DEST_DIR}/${BIN_NAME}"
    cp "${SOURCE}" "${DESTINATION}"
    chmod 700 "${DESTINATION}"
  else
    echo "couldn't find ${SOURCE}"
    return 1
  fi
}

###############################################################################
# Fetches binaries needed by device manager installation.
# Globals:
#   BIN_NAMES
#   BIN_PACKAGES
#   VANADIUM_ROOT
# Arguments:
#   destination for binaries
#   source of binaries
# Returns:
#   None
###############################################################################
get_binaries() {
  local -r BIN_INSTALL="$1"
  local -r BIN_SOURCE="$2"

  local bin_names_str=""
  for bin_name in "${BIN_NAMES[@]}"; do
    bin_names_str+=" ${bin_name}"
  done

  # If source is not specified, try to build latest version of the binaries and copy
  # them from the repository.
  if [[ -z "${BIN_SOURCE}" ]]; then
    if [[ -z "${VANADIUM_ROOT}" ]]; then
      echo 'WARNING: VANADIUM_ROOT is not specified, cannot build fresh binaries'
      return
    fi
    local -r REPO_BIN_DIR="${VANADIUM_ROOT}/release/go/bin"
    echo "Building and Fetching binaries:${bin_names_str} from build repository: ${REPO_BIN_DIR} ..."
    for package in "${BIN_PACKAGES[@]}"; do
       local bin_name=$(basename "${package}")
       v23 go install "${package}" 2> /dev/null || echo "WARNING: Could not build binary: ${bin_name}"
       # while the build failed, we still try to see if we can copy the binary from the build repository.
       copy_binary "${bin_name}" "${REPO_BIN_DIR}" "${BIN_INSTALL}" || echo "WARNING: Could not copy binary: ${bin_name} from build repository: ${REPO_BIN_DIR}"
    done
    return
  fi

  # If the source is specified as an existing local filesystem path,
  # look for the binaries there.
  if [[ -d "${BIN_SOURCE}" ]]; then
      echo "Fetching binaries:${bin_names_str} locally from: ${BIN_SOURCE} ..."
      for bin_name in "${BIN_NAMES[@]}"; do
        copy_binary "${bin_name}" "${BIN_SOURCE}" "${BIN_INSTALL}" || echo "WARNING: Could not copy binary: ${bin_name} from: ${BIN_SOURCE}"
      done
      return
  fi

  # If the source looks like a URL, use HTTP to fetch.
  local -r URL_REGEXP='^(https?|ftp|file)://'
  if [[ "${BIN_SOURCE}" =~ ${URL_REGEXP} ]]; then
    echo "Fetching binaries:${bin_names_str} remotely from: ${BIN_SOURCE} ..."
      for bin_name in "${BIN_NAMES[@]}"; do
        local DEST="${BIN_INSTALL}/${bin_name}"
        (curl -f -o "${DEST}" "${BIN_SOURCE}/${bin_name}" && chmod 700 "${DEST}") || echo "WARNING: Could not fetch binary: ${bin_name} from HTTP server: ${BIN_SOURCE}/${bin_name}"
      done
      return
  fi

  echo "WARNING: couldn't fetch binaries."
}

main() {
  if [[ ! -z "${VBASH_INDICATOR}" ]]; then
    echo "Disallowing running VBASH within VBASH."
    echo "https://memegen.googleplex.com/5551020600983552"
    exit 1
  fi
  export VBASH_INDICATOR="1"

  local -r INSTALL_DIR="${HOME}/.vbash"
  if [[ ! -e "${INSTALL_DIR}" ]]; then
    mkdir -m 700 "${INSTALL_DIR}"
  fi
  if [[ ! -d "${INSTALL_DIR}" ]]; then
    echo "${INSTALL_DIR} is not a directory!"
    exit 1
  fi

  local -r BIN_INSTALL="${INSTALL_DIR}/bin"
  if [[ ! -e "${BIN_INSTALL}" ]]; then
    mkdir -m 700 "${BIN_INSTALL}"
  fi
  if [[ ! -d "${BIN_INSTALL}" ]]; then
    echo "${BIN_INSTALL} is not a directory!"
    exit 1
  fi

  # Fetch the binaries.
  local -r BIN_SOURCE="$1"
  get_binaries "${BIN_INSTALL}" "${BIN_SOURCE}"
  for bin_name in "${BIN_NAMES[@]}"; do
    local BINARY="${BIN_INSTALL}/${bin_name}"
    if [[ ! -s "${BINARY}" ]]; then
      echo "${BINARY} is empty."
      exit 1
    fi
  done
  echo "Using binaries in ${BIN_INSTALL}."

  # Set up the script to be run by the agent.  It first optionally seeks a
  # blessing, and then runs an interactive shell.

  local -r CREDENTIALS_DIR="${INSTALL_DIR}/principal"
  if [[ ! -d "${CREDENTIALS_DIR}" ]]; then
    SEEK_BLESSING="1"
  fi

  # Use a custom rcfile to optionally get a blessing and also to modify the
  # shell prompt to include the default veyron blessing.
  cat <<EOF > "${INSTALL_DIR}/rcfile"
if [[ Darwin == "$(uname)" ]]; then
  if [[ -r /etc/profile ]]; then . /etc/profile; fi
  for n in ~/.bash_profile ~/.bash_login ~/.profile; do
    if [[ -r "$n" ]]; then
      . "$n"
      break
    fi
  done
else
  if [[ -f ~/.bashrc ]]; then . ~/.bashrc; fi
fi
if [[ "${SEEK_BLESSING}" -eq "1" ]]; then
  "${BIN_INSTALL}/principal" seekblessings
fi
GREENBOLD="\[\033[1;32m\]"
default_blessing() {
  "${BIN_INSTALL}/principal" dump | grep "Default blessings" | sed -e 's/Default blessings: //'
}
export PS1="\${PS1}(\${GREENBOLD}\$(default_blessing)\[\033[0m\])$ "
EOF

VEYRON_CREDENTIALS="${CREDENTIALS_DIR}" exec "${BIN_INSTALL}/agentd" --additional_principals="${CREDENTIALS_DIR}" bash --rcfile "${INSTALL_DIR}/rcfile"
}

main "$@"
