#!/bin/bash
# Copyright 2015 The Vanadium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
#
# 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/x/ref/cmd/principal v.io/x/ref/services/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
#   V23_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 "${V23_ROOT}" ]]; then
      echo 'WARNING: V23_ROOT is not specified, cannot build fresh binaries'
      return
    fi
    local -r REPO_BIN_DIR="${V23_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 vanadium 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
export PROMPT_COMMAND='PS1="\u@\h (\[\e[1;32m\]\$("${BIN_INSTALL}/principal" dump -s)\[\e[0m\]):\w \$ "'

EOF

V23_CREDENTIALS="${CREDENTIALS_DIR}" exec "${BIN_INSTALL}/agentd" --additional-principals="${CREDENTIALS_DIR}" bash --rcfile "${INSTALL_DIR}/rcfile"
}

main "$@"
