#!/bin/bash

# The bazel script calls this instead of the bazel-real binary which is
# installed next to it. This script downloads a specific version of Bazel and
# then calls that.

# Alternatively, if the environment variable BAZEL_OVERRIDE is set, that will be
# run directly (after printing a message). That is intended for testing only.

# This script operates based on the assumption that any directory of the correct
# name is a fully extracted, valid Bazel installation. It is careful to avoid
# putting an invalid directory at that name at any point.

set -e
set -u
set -o pipefail

if [[ -n "${BAZEL_OVERRIDE+x}" ]]; then
  tput setaf 1 >&2
  echo -n "Actually calling " >&2
  tput setaf 3 >&2
  echo "${BAZEL_OVERRIDE}" >&2
  tput sgr0 >&2
  exec "${BAZEL_OVERRIDE}" "$@"
fi

readonly VERSION="0.19.0rc4-201810201638+ac88041"

readonly DOWNLOAD_DIR="${HOME}/.cache/bazel"
# Directory to unpack bazel into.  This must change whenever bazel changes.
readonly VERSION_DIR="${DOWNLOAD_DIR}/${VERSION}-v1"
readonly VERSION_BAZEL="${VERSION_DIR}/usr/bin/bazel"

# Creating might fail if another invocation is racing us.
if [[ ! -d "${DOWNLOAD_DIR}" ]]; then
  mkdir -p "${DOWNLOAD_DIR}" || true
fi
if [[ ! -d "${DOWNLOAD_DIR}" ]]; then
  echo "Failed to create ${DOWNLOAD_DIR}" >&2
  exit 1
fi

readonly INSTALLER_NAME="bazel_${VERSION}.xz"
readonly DOWNLOAD_URL="https://www.frc971.org/Build-Dependencies/${INSTALLER_NAME}"

if [[ ! -d "${VERSION_DIR}" ]]; then
  echo "Downloading Bazel version ${VERSION} from ${DOWNLOAD_URL}..." >&2

  # A temporary directory which is definitely on the same filesystem as our final
  # destination, which is important so we can atomically move it.
  # If this move is non-atomic, then a concurrent Bazel command (like the verifier
  # uses several of) could use a half-copied Bazel installation.
  mkdir -p "${HOME}/.cache/bazel"
  DOWNLOAD_TEMP_DIR="$(mktemp --directory --tmpdir="${HOME}/.cache/bazel")"
  TEMP_DIR="$(mktemp --directory --tmpdir="${DOWNLOAD_DIR}")"
  readonly DOWNLOAD_TEMP_DIR
  readonly TEMP_DIR

  ( cd "${DOWNLOAD_TEMP_DIR}"
    # Now, download into the ~/.cache folder
    if [ ! -e "${HOME}/.cache/bazel/${INSTALLER_NAME}" ];
    then
      NOISINESS=--silent
      if [ -t 0 ] ; then
        echo on terminal
        NOISINESS=
      fi
      curl --output "${INSTALLER_NAME}" "${DOWNLOAD_URL}" ${NOISINESS}
      mv "${INSTALLER_NAME}" "${HOME}/.cache/bazel/${INSTALLER_NAME}"
    fi
    rm -rf "${DOWNLOAD_TEMP_DIR}"
  )

  ( cd "${TEMP_DIR}"
    echo "Unpacking Bazel version ${VERSION}..." >&2
    mkdir -p extracted/usr/bin
    xz -d ${HOME}/.cache/bazel/${INSTALLER_NAME} -c > extracted/usr/bin/bazel-real
    chmod a+x extracted/usr/bin/bazel-real
  )

  touch "${TEMP_DIR}/extracted/usr/bin/bazel.bazelrc"

  # Careful: somebody else might have already done it. If they manage to make
  # the move between our check and our move, then we'll end up with a random
  # extracted directory which won't do anybody any harm. If somebody else does
  # that first, then our move will fail.
  if [[ ! -d "${VERSION_DIR}" ]]; then
    mv "${TEMP_DIR}/extracted" "${VERSION_DIR}" || true
  fi
  if [[ ! -d "${VERSION_DIR}" ]]; then
    echo "Failed to create ${VERSION_DIR}" >&2
    exit 1
  fi
  rm -rf "${TEMP_DIR}"
  echo "Done downloading Bazel version ${VERSION}"
fi

ENVIRONMENT_VARIABLES=()
ENVIRONMENT_VARIABLES+=(HOSTNAME="${HOSTNAME}")
ENVIRONMENT_VARIABLES+=(SHELL="${SHELL}")
ENVIRONMENT_VARIABLES+=(USER="${USER}")
ENVIRONMENT_VARIABLES+=(PATH="/usr/bin:/bin")
ENVIRONMENT_VARIABLES+=(HOME="${HOME}")
ENVIRONMENT_VARIABLES+=(TERM="${TERM}")
ENVIRONMENT_VARIABLES+=(LANG="${LANG:-C}")

if [[ ! -z "${DISPLAY+x}" ]]; then
  ENVIRONMENT_VARIABLES+=(DISPLAY="${DISPLAY}")
fi

if [[ ! -z "${LOGNAME+x}" ]]; then
    ENVIRONMENT_VARIABLES+=(LOGNAME="${LOGNAME}")
fi

if [[ -x "${VERSION_BAZEL}-real" ]]; then
  exec -a "${VERSION_BAZEL}" env -i \
      "${ENVIRONMENT_VARIABLES[@]}" \
      "${VERSION_BAZEL}-real" "$@"
fi
if [[ -x "${VERSION_BAZEL}" ]]; then
  exec env -i \
      "${ENVIRONMENT_VARIABLES[@]}" \
      "${VERSION_BAZEL}" "$@"
fi

echo "Can't find the real bazel!" >&2
exit 1
