#!/bin/bash
# This script is deprecated and should not be used for installation.
# This was once a script that was used to install Bitfusion from a tarball.
# It is no longer used for that purpose. Now, it is used to copy files from the
# tarball to the correct location so that they can be packaged
# for installation in a deb or rpm package.
# In the future it will be removed.

# These ShellCheck directives apply to the entire script
# Disable SC2164 "Use cd ... || exit in case cd fails." since we use check_cmd to test for failure.
# shellcheck disable=2164
true

shopt -s nocasematch

BF_BASE_DIR="${BF_BASE_DIR:-}"

# Local installs don't have Jenkins's version of the VERSION file that is made on publish.
# We can't auto fail if we don't find the file.
if [ -f ./VERSION ]; then
  # shellcheck source=/dev/null
  source ./VERSION
  BF_SHORT_SHA=$(echo "$GIT_COMMIT" | cut -c1-8)
else
  VERSION="local"
  BF_SHORT_SHA='deadc0de'
  GIT_COMMIT='deadc0dedeadc0dedeadc0dedeadc0dedeadc0dedeadc0de'
fi

BF_PACKAGE_SRC="${BF_PACKAGE_SRC:-https://s3.amazonaws.com/prod-us-east-1-boost-deploy/bitfusion}"
BF_VERSION="${BF_VERSION:-$VERSION}"
BF_DEPS_ONLY="${BF_DEPS_ONLY:-0}"
BF_OVERWRITE="${BF_OVERWRITE:-0}"
BF_INSTALL_BFA_SERVICE="${BF_INSTALL_BFA_SERVICE:-0}"
BF_INSTALL_BFM_SERVICE="${BF_INSTALL_BFM_SERVICE:-0}"
BF_INSTALL_SRS_SERVICE="${BF_INSTALL_SRS_SERVICE:-0}"
BF_INSTALL_ADAPTOR="${BF_INSTALL_ADAPTOR:-1}"
BF_INSTALL_ADAPTOR_ONLY="${BF_INSTALL_ADAPTOR_ONLY:-0}"
BF_INSTALL_ARCH="${BF_INSTALL_ARCH:-$(uname -m)}"
BF_HOME_PATH="${BF_BASE_DIR}${BF_HOME_PATH:-$HOME/.bitfusion}"
BF_INSTALL_LOG="${BF_INSTALL_LOG}:-${BF_HOME_PATH}/bf_install.log}"
BF_SHARE_DIR="${BF_BASE_DIR}${BF_SHARE_DIR:-/usr/share/bitfusion}"
BF_OPT_DIR="${BF_BASE_DIR}${BF_OPT_DIR:-/opt/bitfusion}"
BF_ETC_DIR="${BF_BASE_DIR}${BF_ETC_DIR:-/etc/bitfusion}"
BF_UNINSTALL_SCRIPT="install"


create_install_log() {
  mkdir -p "${BF_HOME_PATH}"
  touch "${BF_INSTALL_LOG}"
  chown -R "${SUDO_USER}:${SUDO_USER}" "${BF_HOME_PATH}"
}

report_log() {
  LOG_PREFIX=""
  if [ "$1" = "w" ]; then
    LOG_PREFIX="WARNING: "
  fi
  if [ "$1" = "e" ]; then
    LOG_PREFIX="ERROR: "
    echo "$LOG_PREFIX$2"
  fi
  echo "$LOG_PREFIX$2" >> "${BF_INSTALL_LOG}"
  #| tee -a -- we don't want regular reports going to the output
}

warn_cmd() {
  # shellcheck disable=2181
  if [ $? -ne 0 ]; then
    report_log "w" "$1"
  fi
}

exit_log() {
  LOG_PREFIX="$1: "
  echo "$LOG_PREFIX$2" | tee -a "${BF_INSTALL_LOG}"
  exit "$1"
}

check_cmd() {
  last_exit_val=$?
  if [ $last_exit_val -ne 0 ]; then
    # exit_log should terminate the script after logging error
    HELP_MSG=$'.  Exiting...\nPlease refer to docs.bitfusion.io for installation requirements or contact bf-support@vmware.com'
    exit_log "$last_exit_val" "$1$HELP_MSG"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#   NAME: check_nvidia_smi
#   DESCRIPTION:  Need a working nvidia-smi or BFA will crash
#-----------------------------------------------------------------------------------------------------------------------
check_nvidia_smi() {
  if [ -z "${BF_BASE_DIR}" ]; then
    report_log "i" "Testing for nvidia-smi"
    command -v nvidia-smi; check_cmd "Cannot find nvidia-smi. Bitfusion Analytics requires a server with working Nvidia GPUs."
    nvidia-smi -L > /dev/null 2>&1; check_cmd "Cannot run nvidia-smi. Bitfusion Analytics requires a server with working nvidia-smi"
  else
    report_log "i" "BF_BASE_DIR defined, skipping test for nvidia-smi"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#   NAME: check_previous_version
#   DESCRIPTION:  This will prompt if we want to replace a previously installed version
#-----------------------------------------------------------------------------------------------------------------------
check_previous_version() {
  PROMPT_NEEDED=0

  if [ "$BF_OVERWRITE" -eq 1 ]; then
    return
  fi

  P="${BF_BASE_DIR}/usr/bin/bitfusion"
  P="${P} ${BF_OPT_DIR}"
  P="${P} ${BF_BASE_DIR}/lib/systemd/system/bitfusion-analytics.service"
  P="${P} ${BF_BASE_DIR}/lib/systemd/system/bitfusion-manager.service"
  P="${P} ${BF_BASE_DIR}/lib/systemd/system/bitfusion-srs.service"
  P="${P} ${BF_BASE_DIR}/lib/systemd/system/bitfusion.service"

  if (command -v bitfusion); then
    PROMPT_NEEDED=1
  else
    for p in $P; do
      if [[ -e $p ]]; then
        PROMPT_NEEDED=1
        break
      fi
    done
  fi

  if [[ $PROMPT_NEEDED -ne 0 ]]; then
    echo "Previous installation of Bitfusion detected"
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Are you sure you want to overwrite the existing Bitfusion? [y/n]: " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Nn]$ ]]; then
        report_log "i" "User aborted installtion"
        exit_log 7 "Aborting installation"
      elif [[ $REPLY =~ ^[Yy]$ ]]; then
        export BF_OVERWRITE=1
        DONE=1
      else
        echo "Invalid response: ${REPLY}"
      fi
    done
  fi
}

check_bf_install_mode() {
  PROMPT_NEEDED=0
  if [ -z "$BF_INSTALL_MODE" ]; then
    SERVICE_COUNT=0
    BF_INSTALL_MODE="client"
    if [ -f linux/common/bitfusion-analytics.service ]; then
      SERVICE_COUNT=$((SERVICE_COUNT + 1))
      BF_INSTALL_MODE="fda"
    fi
    if [ -f linux/common/bitfusion-manager.service ]; then
      SERVICE_COUNT=$((SERVICE_COUNT + 1))
      BF_INSTALL_MODE="server"
    fi
    if [ -f linux/common/bitfusion-srs.service ]; then
      SERVICE_COUNT=$((SERVICE_COUNT + 1))
      BF_INSTALL_MODE="srs"
    fi
    if [[ $SERVICE_COUNT -gt 1 ]]; then
      PROMPT_NEEDED=1
    fi
  fi

  if [[ $PROMPT_NEEDED -ne 0 ]]; then
    if [[ $BF_SILENT_INSTALL -ne 0 ]]; then
      exit_log 9 "Aborting improperly configured silent install. Mode missing."
    fi

    echo "Select one of the following installation modes:"
    echo "  1 - Bitfusion client binaries only (no systemd service)"
    echo "  2 - Bitfusion Analytics service (no license required)"
    echo "  3 - Bitfusion Server and Adapter (license required)"
    echo "  4 - Bitfusion SRS service (license required)"
    echo "  5 - Adapter only"
    echo "  6 - Server only"
    echo
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Select installation mode [1/2/3/4]: " -n 1 -r
      echo
      case "$REPLY" in
        '1')
          BF_INSTALL_MODE="client"
          DONE=1
          ;;
        '2')
          BF_INSTALL_MODE="fda"
          DONE=1
          ;;
        '3')
          BF_INSTALL_MODE="server"
          DONE=1
          ;;
        '4')
          BF_INSTALL_MODE="srs"
          DONE=1
          ;;
        '5')
          BF_INSTALL_MODE="adaptor-only"
          DONE=1
          ;;
        '6')
          BF_INSTALL_MODE="server-only"
          DONE=1
          ;;
        *)
          echo "Invalid response: ${REPLY}"
          ;;
      esac
    done
  fi

  echo "Installation mode: $BF_INSTALL_MODE"

  BF_INSTALL_ADAPTOR=1
  case "$BF_INSTALL_MODE" in
    'binaries')
      # Same as "client"
      ;&
    'client')
      ;;
    'fda')
      # At this point we require that nvidia-smi is available
      check_nvidia_smi
      BF_INSTALL_BFA_SERVICE=1
      ;;
    'fdm')
      # Same as "server"
      ;&
    'server')
      # At this point we require that nvidia-smi is available
      check_nvidia_smi
      BF_INSTALL_BFM_SERVICE=1
      ;;
    'server-only')
      BF_INSTALL_BFM_SERVICE=1
      BF_INSTALL_ADAPTOR=0
      ;;
    'adaptor-only')
      BF_INSTALL_ADAPTOR=1
      BF_INSTALL_ADAPTOR_ONLY=1
      ;;
    'srs')
      # At this point we require that nvidia-smi is available
      check_nvidia_smi
      BF_INSTALL_SRS_SERVICE=1
      ;;
    *)
      exit_log 9 "Invalid Bitfusion installation mode detected: ${BF_INSTALL_MODE}"
      ;;
  esac
}


#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  select_os
#   DESCRIPTION:  Dertermines the OS type and version
#-----------------------------------------------------------------------------------------------------------------------
select_os() {
  # Probe for platform
  if [ -f /etc/os-release ]; then
    # Will match on Centos 7, Centos 8, RHEL 8, SLES15, Ubuntu 16.04, Ubuntu 18.04, Photon 3.0
    # shellcheck source=/dev/null
    . /etc/os-release
    DISTRIB_ID=${ID,,}
    DISTRIB_RELEASE=${VERSION_ID}

    # For RHEL support we ignore minor releases
    if [ "${ID}" == "rhel" ] || [ "${ID}" == "rocky" ]; then
      DISTRIB_RELEASE=${VERSION_ID/.*/}
    fi
  else
    exit_log 1 "Unable to determine OS flavor"
  fi


  report_log "i" "OS flavor is ${DISTRIB_ID}-${DISTRIB_RELEASE}"
  export DISTRIB_ID
  export DISTRIB_RELEASE
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_bitfusion_deps_ubuntu
#   DESCRIPTION:  Function to get a list of Bitfusion dependencies on ubuntu systems
#                 Supported:
#                   Ubuntu 16.04 LTS
#                   Ubuntu 18.04 LTS
#-----------------------------------------------------------------------------------------------------------------------
get_bitfusion_deps_ubuntu() {
  INSTALL_DEPS=""

  if [[ "$DISTRIB_RELEASE" = "18.04" ]]; then
    INSTALL_DEPS="wget libibverbs1 ibverbs-providers libnuma1 libcapstone3 open-vm-tools libcap2-bin"
  elif [[ "$DISTRIB_RELEASE" = "20.04" ]]; then
    INSTALL_DEPS="wget libibverbs1 ibverbs-providers libnuma1 libcapstone3 open-vm-tools libcap2-bin"
  elif [[ "$DISTRIB_RELEASE" = "22.04" ]]; then
    INSTALL_DEPS="wget libibverbs1 ibverbs-providers libnuma1 libcapstone4 open-vm-tools libcap2-bin"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_missing_deps_ubuntu
#   DESCRIPTION:  Function to get a list of missing dependencies on ubuntu systems
#                 Supported:
#                   Ubuntu 16.04 LTS
#                   Ubuntu 18.04 LTS
#-----------------------------------------------------------------------------------------------------------------------
get_missing_deps_ubuntu() {
  MISSING_DEPS=""
  for d in "$@"; do
    if ! (dpkg -S "$d"); then
      MISSING_DEPS="$MISSING_DEPS $d"
    fi
  done
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_deps_ubuntu
#   DESCRIPTION:  Function to install Bitfusion on ubuntu systems
#                 Supported:
#                   Ubuntu 16.04 LTS and 18.04 LTS
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_deps_ubuntu() {
  report_log "i" "Checking if should install dependencies (Ubuntu $DISTRIB_RELEASE)"

  if [[ $BF_NODEPS ]]; then
    report_log "i" "Skipping dependencies (Ubuntu $DISTRIB_RELEASE)"
    return 0
  fi

  # Figure out which dependencies are missing
  get_bitfusion_deps_ubuntu
  # shellcheck disable=2086
  get_missing_deps_ubuntu $INSTALL_DEPS

  INSTALL_NEEDED=0
  if [[ "$MISSING_DEPS" != "" ]]; then
    if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
      echo "We need to install the following missing dependencies: ${MISSING_DEPS}"
      DONE=0
      while [[ $DONE -ne 1 ]]; do
        read -p "Would you like to install them now? [y/n]: " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
          INSTALL_NEEDED=1
          DONE=1
        elif [[ $REPLY =~ ^[Nn]$ ]]; then
          echo "Skipping dependencies installation"
          report_log "i" "User skipping dependencies installation (Ubuntu $DISTRIB_RELEASE)"
          DONE=1
        else
          echo "Invalid response: ${REPLY}"
        fi
      done
    else
      INSTALL_NEEDED=1
    fi
  fi

  if [[ $INSTALL_NEEDED -eq 1 ]]; then
    echo "Installing Bitfusion dependencies: ${MISSING_DEPS}..."
    apt-get -y -qq update; check_cmd "Error with apt-get update (Ubuntu $DISTRIB_RELEASE)"
    # shellcheck disable=2086
    apt-get -y -qq install ${MISSING_DEPS}
    check_cmd "Error: apt install dependencies (Ubuntu $DISTRIB_RELEASE)"
    echo "Installing Bitfusion dependencies completed."

    report_log "i" "Installed dependencies (Ubuntu $DISTRIB_RELEASE): ${MISSING_DEPS}"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_bitfusion_deps_centos
#   DESCRIPTION:  Function to get a list of Bitfusion dependencies on centos systems
#                 Supported:
#                   Centos 7, 8
#-----------------------------------------------------------------------------------------------------------------------
get_bitfusion_deps_centos() {
    INSTALL_DEPS="wget libibverbs numactl-libs capstone libnl3-devel open-vm-tools libcap"
}

get_bitfusion_deps_rhel() {
    INSTALL_DEPS="wget libibverbs numactl-libs capstone libnl3-devel open-vm-tools libcap"
}

get_bitfusion_deps_sles() {
    INSTALL_DEPS="wget libibverbs numactl capstone libnl3-200 open-vm-tools libcap-progs"
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_missing_deps_centos
#   DESCRIPTION:  Function to get a list of missing dependencies on centos systems
#                 Supported:
#                   Centos 7
#-----------------------------------------------------------------------------------------------------------------------
get_missing_deps_centos() {
  MISSING_DEPS=""
  for d in "$@"; do
    if ! (yum --noplugins list installed "$d"); then
      MISSING_DEPS="$MISSING_DEPS $d"
    fi
  done
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_deps_centos
#   DESCRIPTION:  Function to install Bitfusion on Centos systems
#                 Supported:
#                   Centos 6.6
#                   Centos 6.7
#                   Centos 7.0
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_deps_centos() {
  report_log "i" "Checking if should install dependencies (CentOS and compatible $DISTRIB_RELEASE)"

  if [[ $BF_NODEPS ]]; then
    report_log "i" "Skipping dependencies (CentOS and compatible $DISTRIB_RELEASE)"
    return 0
  fi

  # Figure out which dependencies are missing
  get_bitfusion_deps_centos
  # shellcheck disable=2086
  get_missing_deps_centos $INSTALL_DEPS

  INSTALL_NEEDED=0
  if [[ "$MISSING_DEPS" != "" ]]; then
    if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
      echo "We need to install the following missing dependencies: ${MISSING_DEPS}"
      DONE=0
      while [[ $DONE -ne 1 ]]; do
        read -p "Would you like to install them now? [y/n]: " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
          INSTALL_NEEDED=1
          DONE=1
        elif [[ $REPLY =~ ^[Nn]$ ]]; then
          echo "Skipping dependencies installation"
          report_log "i" "User skipping dependencies installation (CentOS and compatible $DISTRIB_RELEASE)"
          DONE=1
        else
          echo "Invalid response: ${REPLY}"
        fi
      done
    else
      INSTALL_NEEDED=1
    fi
  fi

  if [[ $INSTALL_NEEDED -eq 1 ]]; then
    echo "Installing Bitfusion dependencies: ${MISSING_DEPS}..."
    # shellcheck disable=2086
    yum install -y -e 0 -q ${MISSING_DEPS} ; check_cmd "Error: yum install dependencies (CentOS and compatible $DISTRIB_RELEASE)"
    echo "Installing Bitfusion dependencies completed."
    report_log "i" "Installed dependencies (CentOS and compatible $DISTRIB_RELEASE): ${MISSING_DEPS}"
  fi

}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_bitfusion_deps_photon
#   DESCRIPTION:  Function to get a list of Bitfusion dependencies on photon systems
#                 Supported:
#                   Photon 3.0 and 4.0
#-----------------------------------------------------------------------------------------------------------------------
get_bitfusion_deps_photon() {
  INSTALL_DEPS=""

  if [[ "$DISTRIB_RELEASE" = "3.0" || "$DISTRIB_RELEASE" = "4.0" ]]; then
    INSTALL_DEPS="wget librdmacm libibverbs numactl capstone libnl open-vm-tools shadow-tools libcap"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  get_missing_deps_photon
#   DESCRIPTION:  Function to get a list of missing dependencies on photon systems
#                 Supported:
#                   Photon 3.0
#-----------------------------------------------------------------------------------------------------------------------
get_missing_deps_photon() {
  MISSING_DEPS=""
  for d in "$@"; do
    if ! (tdnf list installed "$d"); then
      MISSING_DEPS="$MISSING_DEPS $d"
    fi
  done
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_deps_photon
#   DESCRIPTION:  Function to install Bitfusion on Photon systems
#                 Supported:
#                   Photon 3.0
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_deps_photon() {
  report_log "i" "Checking if should install dependencies (Photon and compatible $DISTRIB_RELEASE)"

  if [[ $BF_NODEPS ]]; then
    report_log "i" "Skipping dependencies (Photon and compatible $DISTRIB_RELEASE)"
    return 0
  fi

  # Figure out which dependencies are missing
  get_bitfusion_deps_photon
  # shellcheck disable=2086
  get_missing_deps_photon $INSTALL_DEPS

  INSTALL_NEEDED=0
  if [[ "$MISSING_DEPS" != "" ]]; then
    if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
      echo "We need to install the following missing dependencies: ${MISSING_DEPS}"
      DONE=0
      while [[ $DONE -ne 1 ]]; do
        read -p "Would you like to install them now? [y/n]: " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
          INSTALL_NEEDED=1
          DONE=1
        elif [[ $REPLY =~ ^[Nn]$ ]]; then
          echo "Skipping dependencies installation"
          report_log "i" "User skipping dependencies installation (Photon and compatible $DISTRIB_RELEASE)"
          DONE=1
        else
          echo "Invalid response: ${REPLY}"
        fi
      done
    else
      INSTALL_NEEDED=1
    fi
  fi

  if [[ $INSTALL_NEEDED -eq 1 ]]; then
    echo "Installing Bitfusion dependencies: ${MISSING_DEPS}..."
    # shellcheck disable=2086
    tdnf install -y -q ${MISSING_DEPS} ; check_cmd "Error: tdnf install dependencies (Photon and compatible $DISTRIB_RELEASE)"
    echo "Installing Bitfusion dependencies completed."
    report_log "i" "Installed dependencies (Photon and compatible $DISTRIB_RELEASE): ${MISSING_DEPS}"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_srs_systemd_service
#   DESCRIPTION:  Function to install Bitfusion SRS service on systemd systems
#                 Supported:
#                   Centos 7.0
#                   Ubuntu 16.04
#                   Ubuntu 18.04
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_srs_systemd_service() {
  echo -e "Installing Bitfusion SRS systemd service"
  report_log "i" "Installing Bitfusion SRS systemd service"

  START_SERVICE=1
  if ! (command -v systemctl); then
    report_log "w" "Systemd not found."
    START_SERVICE=0
  fi

  if [[ ! -f ${BF_OPT_DIR}/service/bitfusion-srs.service ]]; then
    report_log "e" "srs service not available for this release. Aborting service installation"
    exit 1
  fi

  mkdir -p "${BF_BASE_DIR}/lib/systemd/system/"; check_cmd "Error: add Bitfusion SRS systemd service"
  cp -p "${BF_OPT_DIR}/service/bitfusion-srs.service" "${BF_BASE_DIR}/lib/systemd/system/bitfusion-srs.service"
  systemctl enable bitfusion-srs

  if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Do you want to start the bitfusion-srs service? [y/n]: " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Yy]$ ]]; then
        DONE=1
      elif [[ $REPLY =~ ^[Nn]$ ]]; then
        report_log "i" "User skipping service start"
        START_SERVICE=0
        DONE=1
      else
        echo "Invalid response: ${REPLY}"
      fi
    done
  fi

  if [[ ! -f ${BF_ETC_DIR}/lic/license.txt ]]; then
    echo "This system is unlicensed. Please run \"sudo bitfusion init\" before starting the service"
    START_SERVICE=0
  fi

  if [[ $START_SERVICE -eq 1 ]]; then
    systemctl start bitfusion-srs
    sleep 1
    if ! (systemctl status bitfusion); then
      report_log "e" "Bitfusion SRS service failed to start"
      echo "You can check out the logs to help troubleshoot via: journalctl -xe"
    else
      echo -e "Bitfusion SRS systemd service started successfully"
      IP=$(ip route get 1 2>/dev/null | awk '{print $NF;exit}')
      # shellcheck disable=2181
      if [[ $? -eq 0 && -n $IP ]];then
        echo "Bitfusion SRS will start listening on $IP:56001 shortly"
      fi
    fi
  else
    echo "To start the service manually do: sudo systemctl start bitfusion-srs"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_analytics_systemd_service
#   DESCRIPTION:  Function to install Bitfusion Analytics service on systemd systems
#                 Supported:
#                   Centos 7.0
#                   Ubuntu 16.04
#                   Ubuntu 18.04
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_analytics_systemd_service() {
  echo -e "Installing Bitfusion Analytics systemd service"
  report_log "i" "Installing Bitfusion Analytics systemd service"

  START_SERVICE=1
  if ! (command -v systemctl); then
    report_log "w" "Systemd not found."
    START_SERVICE=0
  fi

  if [[ ! -f ${BF_OPT_DIR}/service/bitfusion-analytics.service ]]; then
    report_log "e" "analytics service not available for this release. Aborting service installation"
    exit 1
  fi

  mkdir -p "${BF_BASE_DIR}/lib/systemd/system/"; check_cmd "Error: add bitfusion analytics systemd service"
  cp -p "${BF_OPT_DIR}/service/bitfusion-analytics.service" "${BF_BASE_DIR}/lib/systemd/system/bitfusion-analytics.service"
  systemctl daemon-reload
  systemctl enable bitfusion-analytics

  if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Do you want to start the bitfusion-analytics service? [y/n]: " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Yy]$ ]]; then
        DONE=1
      elif [[ $REPLY =~ ^[Nn]$ ]]; then
        report_log "i" "User skipping service start"
        START_SERVICE=0
        DONE=1
      else
        echo "Invalid response: ${REPLY}"
      fi
    done
  fi

  if [[ $START_SERVICE -eq 1 ]]; then
    systemctl start bitfusion-analytics
    sleep 1
    if ! (systemctl status bitfusion-analytics); then
      report_log "e" "bitfusion-analytics service failed to start"
      echo "You can check out the logs to help troubleshoot via: journalctl -xe"
    else
      echo -e "Bitfusion Analytics systemd service started successfully"
      IP=$(ip route get 1 2>/dev/null | awk '{print $NF;exit}')
      # shellcheck disable=2181
      if [[ $? -eq 0 && -n $IP ]];then
        echo "Bitfusion Analytics will start listening on http://$IP:54000 shortly"
      fi
    fi
  else
    echo "To start the service manually do: sudo systemctl start bitfusion-analytics"
  fi
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_manager_systemd_service
#   DESCRIPTION:  Function to install Bitfusion Manager service on systemd systems
#                 Supported:
#                   Centos 7.0
#                   Ubuntu 16.04
#                   Ubuntu 18.04
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_manager_systemd_service() {
  echo -e "Installing Bitfusion Manager systemd service"
  report_log "i" "Installing Bitfusion Manager systemd service"

  START_SERVICE=1
  if ! (command -v systemctl); then
    report_log "w" "Systemd not found."
    START_SERVICE=0
  fi

  if [[ ! -f ${BF_OPT_DIR}/service/bitfusion-manager.service ]]; then
    report_log "e" "manager service not available for this release. Aborting service installation"
    exit 1
  fi

  mkdir -p "${BF_BASE_DIR}/lib/systemd/system/"; check_cmd "Error: add bitfusion manager systemd service"
  cp -p "${BF_OPT_DIR}/service/bitfusion-manager.service" "${BF_BASE_DIR}/lib/systemd/system/bitfusion-manager.service"
  if [ -z "${BF_BASE_DIR}" ]; then
    systemctl daemon-reload
    systemctl enable bitfusion-manager
  else
    report_log "i" "BF_BASE_DIR defined, not enabling bitfusion-manager service"
  fi

  if [[ $BF_SILENT_INSTALL -eq 0 ]]; then
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Do you want to start the bitfusion-manager service? [y/n]: " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Yy]$ ]]; then
        DONE=1
      elif [[ $REPLY =~ ^[Nn]$ ]]; then
        report_log "i" "User skipping service start"
        START_SERVICE=0
        DONE=1
      else
        echo "Invalid response: ${REPLY}"
      fi
    done
  fi

  if [[ ! -f ${BF_ETC_DIR}/lic/license.txt ]]; then
    echo "This system is unlicensed. Please run \"sudo bitfusion init\" before starting the service"
    START_SERVICE=0
  fi

  if [[ $START_SERVICE -eq 1 ]]; then
    systemctl start bitfusion-manager
    sleep 1
    if ! (systemctl status bitfusion-manager); then
      report_log "e" "bitfusion-manager service failed to start"
      echo "You can check out the logs to help troubleshoot via: journalctl -xe"
    else
      echo -e "Bitfusion Manager systemd service started successfully"
      IP=$(ip route get 1 2>/dev/null | awk '{print $NF;exit}')
      # shellcheck disable=2181
      if [[ $? -eq 0 && -n $IP ]];then
        echo "Bitfusion Manager will start listening on http://$IP:54000 shortly"
      fi
    fi
  else
    echo "To start the service manually do: sudo systemctl start bitfusion-manager"
  fi
}


#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_deps_rhel
#   DESCRIPTION:  Function to install Bitfusion on Redhat Enterprise Linux systems
#                 Supported:
#                   RHEL 7, 8
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_deps_rhel() {
  install_bitfusion_deps_centos
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  install_bitfusion_deps_sles
#   DESCRIPTION:  Function to install Bitfusion on SUSE Linux Enterprise Systems
#                 Supported:
#                   SLES 15.3
#-----------------------------------------------------------------------------------------------------------------------
install_bitfusion_deps_sles() {
  install_bitfusion_deps_centos
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  list_bitfusion_deps
#   DESCRIPTION:  Function to list all Bitfusion dependencies
#-----------------------------------------------------------------------------------------------------------------------
list_bitfusion_deps() {
  case ${DISTRIB_ID} in
    ubuntu)
      get_bitfusion_deps_ubuntu
      ;;
    centos)
      get_bitfusion_deps_centos
      ;;
    rocky)
      get_bitfusion_deps_centos
      ;;
    rhel)
      get_bitfusion_deps_rhel
      ;;
    sles)
      get_bitfusion_deps_sles
      ;;
    photon)
      get_bitfusion_deps_photon
      ;;
  esac
  echo "$INSTALL_DEPS"
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  list_bitfusion_missing_deps
#   DESCRIPTION:  Function to list Bitfusion missing dependencies
#-----------------------------------------------------------------------------------------------------------------------
list_bitfusion_missing_deps() {
  case ${DISTRIB_ID} in
    ubuntu)
      get_bitfusion_deps_ubuntu
      # shellcheck disable=2086
      get_missing_deps_ubuntu $INSTALL_DEPS
      ;;
    rhel)
      get_bitfusion_deps_rhel
      # shellcheck disable=2086
      get_missing_deps_centos $INSTALL_DEPS
      ;;
    sles)
      get_bitfusion_deps_sles
      # shellcheck disable=2086
      get_missing_deps_centos $INSTALL_DEPS
      ;;
    centos)
      get_bitfusion_deps_centos
      # shellcheck disable=2086
      get_missing_deps_centos $INSTALL_DEPS
      ;;
    rocky)
      get_bitfusion_deps_centos
      # shellcheck disable=2086
      get_missing_deps_centos $INSTALL_DEPS
      ;;
    photon)
      get_bitfusion_deps_photon
      # shellcheck disable=2086
      get_missing_deps_photon $INSTALL_DEPS
      ;;
  esac
  echo "$MISSING_DEPS"
}

update_ulimits() {
  mkdir -p "${BF_BASE_DIR}/etc/security/limits.d"; check_cmd "Error: mkdir -p ${BF_BASE_DIR}/etc/security/limits.d"

  # Update ulimit settings on clients for the bitfusion user
  if [[ "${BF_INSTALL_MODE}" == 'client' || "${BF_INSTALL_MODE}" == "fda" ]]; then
    cat << 'EOF' > "${BF_BASE_DIR}/etc/security/limits.d/bitfusion-client-limits.conf"
# /etc/security/limits.d/bitfusion-client-limits.conf

# max number of open files (ulimit -n)
@bitfusion soft nofile 100000
@bitfusion hard nofile 100000

# Unlimited locked-in-memory address space (ulimit -l)
@bitfusion soft memlock unlimited
@bitfusion hard memlock unlimited

# Unlimited max resident set size (ulimit -m)
@bitfusion soft rss unlimited
@bitfusion hard rss unlimited
EOF
    chmod 644 "${BF_BASE_DIR}/etc/security/limits.d/bitfusion-client-limits.conf"; check_cmd "Error: chmod 644 ${BF_BASE_DIR}/etc/security/limits.d/bitfusion-client-limits.conf"

  else

    # Update ulimit settings on servers for all users
    cat << 'EOF' > "${BF_BASE_DIR}/etc/security/limits.d/bitfusion-server-limits.conf"
# /etc/security/limits.d/bitfusion-server-limits.conf

# max number of open files (ulimit -n)
root soft nofile 100000
root hard nofile 100000

# Unlimited locked-in-memory address space (ulimit -l)
root soft memlock unlimited
root hard memlock unlimited

# Unlimited max resident set size (ulimit -m)
root soft rss unlimited
root hard rss unlimited

# max number of open files (ulimit -n)
* soft nofile 100000
* hard nofile 100000

# Unlimited locked-in-memory address space (ulimit -l)
* soft memlock unlimited
* hard memlock unlimited

# Unlimited max resident set size (ulimit -m)
* soft rss unlimited
* hard rss unlimited
EOF
    chmod 644 "${BF_BASE_DIR}/etc/security/limits.d/bitfusion-server-limits.conf"; check_cmd "Error: chmod 644 ${BF_BASE_DIR}/etc/security/limits.d/bitfusion-server-limits.conf"

    # Update the arp settings on the server
    mkdir -p "${BF_BASE_DIR}/etc/sysctl.d"; check_cmd "Error: mkdir -p ${BF_BASE_DIR}/etc/sysctl.d"
    cat << 'EOF' > "${BF_BASE_DIR}/etc/sysctl.d/90-bitfusion-network.conf"
# /etc/sysctl.d/90-bitfusion-network.conf

net.ipv4.conf.all.arp_filter = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.all.arp_notify = 1
net.ipv4.conf.all.arp_accept = 0
EOF
    chmod 644 "${BF_BASE_DIR}/etc/sysctl.d/90-bitfusion-network.conf"; check_cmd "Error: chmod 644 ${BF_BASE_DIR}/etc/sysctl.d/90-bitfusion-network.conf"

  fi
}

clean_previous_install() {
  # Do not clean /etc/bitfusion because it can contain user-defined config and license info
  echo "Uninstalling existing version of Bitfusion (if any)..."
  report_log "i" "Uninstalling Bitfusion..."

  for s in bitfusion-analytics bitfusion-manager bitfusion-srs bitfusion; do
    if [[ -f ${BF_BASE_DIR}/lib/systemd/system/${s}.service ]]; then
      report_log "i" "Stopping ${s} service"
      systemctl stop ${s} > /dev/null 2>&1
      systemctl disable ${s} > /dev/null 2>&1
      rm -rf "${BF_BASE_DIR}/lib/systemd/system/${s}.service"; check_cmd "Cannot remove ${BF_BASE_DIR}/lib/systemd/system/${s}.service"
    fi
  done

  P="${BF_HOME_PATH}/.bitfusion/srs.pid"
  P="${P} ${BF_BASE_DIR}/root/.bitfusion/srs.pid"
  P="${P} ${BF_BASE_DIR}/var/run/bitfusion/srs.pid"
  P="${P} ${BF_BASE_DIR}/etc/bash_completion.d/bitfusion"
  P="${P} ${BF_BASE_DIR}/usr/share/bitfusion"
  P="${P} ${BF_BASE_DIR}/usr/bin/bitfusion"
  P="${P} ${BF_BASE_DIR}/opt/bitfusion"
  P="${P} ${BF_BASE_DIR}/etc/security/limits.d/bitfusion-*limits.conf"

  for p in $P; do
    report_log "i" "Removing ${p}"
    rm -rf "${p}"; check_cmd "Cannot remove ${p}"
  done
}

# in case user run install without "U" in /opt/bitfusion/
catch_uninstall_error() {
  uninstall_script_path="${BF_OPT_DIR}/${BF_UNINSTALL_SCRIPT}"
  if [[ ($PWD == "${BF_OPT_DIR}" ) || ( $0 == "${uninstall_script_path}" ) ]]; then
    echo "To uninstall bitfusion, please run:"
    echo " \$ sudo ${uninstall_script_path} -U"
    exit 1
  fi
}

install_bitfusion() {
  if [[ $BF_DEPS_ONLY -ne 1 ]]; then
    report_log "i" "check previous install"
    # We don't prompt about previous versions on silent installations
    if [[ $BF_SILENT_INSTALL -ne 1 ]]; then
      # This will exit the installer if the user does not want to overwrite it
      check_previous_version
    fi
    clean_previous_install

    check_bf_install_mode

    if [ ! -d "linux/${BF_INSTALL_ARCH}/common" ]; then
      exit_log 3 "Error: Unsupported hardware architecture: ${BF_INSTALL_ARCH}. Please contact bf-support@vmware.com"
    fi

    if [ ! -d "linux/${BF_INSTALL_ARCH}/$DISTRIB_ID" ]; then
      exit_log 3 "Error: Invalid installation package or unsupported operating system: $DISTRIB_ID. Please contact bf-support@vmware.com"
    fi
  fi

  # Configure platform specific variables and do dependencies installation
  case ${DISTRIB_ID} in
    ubuntu)
      install_bitfusion_deps_ubuntu
      ;;
    rhel)
      install_bitfusion_deps_rhel
      ;;
    sles)
      install_bitfusion_deps_sles
      ;;
    centos)
      install_bitfusion_deps_centos
      ;;
    rocky)
      install_bitfusion_deps_centos
      ;;
    photon)
      install_bitfusion_deps_photon
      ;;
  esac

  if [[ ${BF_DEPS_ONLY} -eq 1 ]]; then
    report_log "i" "Installation of dependencies complete"
    exit 0
  fi

  if [[ ${BF_INSTALL_ADAPTOR_ONLY} == 0 ]]; then
    # Create required directories
    for d in \
      ${BF_SHARE_DIR} \
      ${BF_OPT_DIR} \
      "${BF_HOME_PATH}" \
      ${BF_ETC_DIR} \
      ${BF_BASE_DIR}/etc/bash_completion.d \
      ${BF_OPT_DIR}/service \
      ${BF_BASE_DIR}/var/cache/bitfusion \
      ${BF_BASE_DIR}/var/run/bitfusion \
      ${BF_BASE_DIR}/usr/bin/ \
      ${BF_BASE_DIR}/usr/share/bitfusion
    do
      report_log "i" "Creating dir: ${d}"
      mkdir -p "${d}"; check_cmd "Error: mkdir -p ${d}"
    done

    report_log "i" "Moving install to ${BF_OPT_DIR}/"
    mv install "${BF_OPT_DIR}/"; check_cmd "Moved install file unsuccessful"
    report_log "i" "Making ${BF_OPT_DIR}/install executable"
    chmod +x "${BF_OPT_DIR}/install"; check_cmd "Error: add execute permission to install script"
  fi

  if [[ ${BF_INSTALL_ADAPTOR} == 0 ]]; then
    report_log "i" "Not installing adaptor_deploy files"
  else
    #Install Core
    # Note:
    #   Use `mv` instead of `cp` to allow Bitfusion to self update. `cp` doesn't work
    #   because it tries to write into the busy inode. `mv` just updates the link, and
    #   the orphaned link will get discarded after the update process exits

    mkdir -p "${BF_OPT_LIB_DIR}"             ; check_cmd "Error: mkdir -p ${BF_OPT_LIB_DIR}"
    mkdir -p "${OLD_BF_OPT_LIB_DIR}"         ; check_cmd "Error: mkdir -p ${OLD_BF_OPT_LIB_DIR}"

    report_log "i" "Moving adaptor_deploy files to ${BF_OPT_LIB_DIR}/"
    mv "linux/${BF_INSTALL_ARCH}/$DISTRIB_ID/$DISTRIB_RELEASE/adaptor_deploy/"{lib,bin} "${BF_OPT_LIB_DIR}/"; check_cmd "Error: moving adaptor_deploy files"

    ORIG_DIR=$(pwd)                          ; check_cmd "Error: getting current directory"

    report_log "i" "Create a relative symlink from the old location for adaptor_deploy files to the new location for adaptor_deploy files"
    cd "${OLD_BF_OPT_LIB_DIR}"               ; check_cmd "Error: could not 'cd ${OLD_BF_OPT_LIB_DIR}'"
    # shellcheck disable=2103
    cd ..                                    ; check_cmd "Error: could not 'cd ..'"
    rmdir bitfusion                          ; check_cmd "Error: could not 'rmdir bitfusion'"
    ln -s "${OLD_TO_NEW_OPT_LIB_SYMLINK[@]}" ; check_cmd "Error: creating relative symlink ${OLD_TO_NEW_OPT_LIB_SYMLINK[*]}"

    report_log "i" "Create a symlink from the full SHA to the version-short_sha directory"
    cd "${BF_OPT_DIR}"                       ; check_cmd "Error: could not 'cd ${BF_OPT_DIR}'"
    ln -s "${SHA_ONLY_SYMLINK[@]}"           ; check_cmd "Error: creating SHA-only symlink ${SHA_ONLY_SYMLINK}"
    ln -sf "${LATEST_SYMLINK[@]}"            ; check_cmd "Error: creating 'latest' symlink ${LATEST_SYMLINK}"

    cd "${ORIG_DIR}"                         ; check_cmd "Error: changing to original directory"

    if [[ "${BF_INSTALL_MODE}" == 'client' ]]; then
      # Remove some binary files from the ${BF_OPT_LIB_DIR}/bin directory that are not needed for client installs
      for b in dispatcher nv-server; do
        rm "${BF_OPT_LIB_DIR}/bin/${b}"; check_cmd "Error: couldn't remove ${BF_OPT_LIB_DIR}/bin/${b} from the client install"
      done
      # Remove the mvl libraries from client installs
      rm -r "${BF_OPT_LIB_DIR}/lib/cuda/mvl/"; check_cmd "Error: couldn't remove ${BF_OPT_LIB_DIR}/lib/cuda/mvl/ from the client install"
      rm -r "${BF_OPT_LIB_DIR}/lib/nvml/mvl/"; check_cmd "Error: couldn't remove ${BF_OPT_LIB_DIR}/lib/nvml/mvl/ from the client install"
    fi
  fi

  # Local installs don't have Jenkins's version of the VERSION file that is made on publish.
  # We can't auto fail if we don't find the file
  if [ -f ./VERSION ]; then
    if [[ ${BF_INSTALL_ADAPTOR_ONLY} == 1 ]]; then
      report_log "i" "Copying VERSION to ${BF_OPT_LIB_DIR}/VERSION"
      mv VERSION "${BF_OPT_LIB_DIR}/VERSION"; check_cmd "cannot copy VERSION to ${BF_OPT_LIB_DIR}/VERSION"
    else
      report_log "i" "Copying VERSION to ${BF_BASE_DIR}/usr/share/bitfusion/VERSION"
      mv VERSION "${BF_BASE_DIR}/usr/share/bitfusion/VERSION"; check_cmd "cannot copy VERSION to ${BF_BASE_DIR}/usr/share/bitfusion/VERSION"
    fi
  fi

  if [[ ${BF_INSTALL_ADAPTOR_ONLY} == 1 ]]; then
    # Nothing else to install
    echo
    echo "adaptor-only installation complete..."
    return 0
  fi

  report_log "i" "Moving bitfusion to ${BF_BASE_DIR}/usr/bin/bitfusion"
  mv "linux/${BF_INSTALL_ARCH}/common/bitfusion" "${BF_BASE_DIR}/usr/bin/bitfusion"; check_cmd "copy to ${BF_BASE_DIR}/usr/bin/bitfusion unsuccessful"
  report_log "i" "Making ${BF_BASE_DIR}/usr/bin/bitfusion executable"
  chmod +x "${BF_BASE_DIR}/usr/bin/bitfusion"; check_cmd "Error: add execute permission to bitfusion"

  if [ -f linux/common/copyright ]; then
    report_log "i" "Copying copyright to ${BF_BASE_DIR}/usr/share/bitfusion/copyright"
    mv linux/common/copyright "${BF_BASE_DIR}/usr/share/bitfusion/copyright"; check_cmd "cannot copy copyright to ${BF_BASE_DIR}/usr/share/bitfusion/copyright"
  fi

  if [[ -d ${BF_BASE_DIR}/etc/bash_completion.d ]]; then
    report_log "i" "Moving bitfusion.autocomplete to ${BF_BASE_DIR}/etc/bash_completion.d/bitfusion"
    mv linux/common/bitfusion.autocomplete "${BF_BASE_DIR}/etc/bash_completion.d/bitfusion"
  fi

  if [[ -f linux/common/cassandra.tmpl && "${BF_INSTALL_MODE}" != 'client' ]]; then
    report_log "i" "Moving cassandra.tmpl to ${BF_ETC_DIR}"
    mv linux/common/cassandra.tmpl "${BF_ETC_DIR}"
  fi

  # Update ulimit settings
  update_ulimits

  # Check to see if we can install the web front end
  if [[ -d static ]]; then
    # Move frontend directory
    mv static/ "${BF_OPT_DIR}/"; check_cmd "Error: failed to move the web frontend assets to ${BF_OPT_DIR}/"
  else
    # In BFA/BFM modes the front end is not optional
    if [[ "${BF_INSTALL_MODE}" == "client" || "${BF_INSTALL_MODE}" == "fda" || "${BF_INSTALL_MODE}" == "server" ]]; then
      exit_log 8 "Could not install web front end"
    fi
  fi

  if (ls linux/common/bitfusion-*.service); then
    if [[ "${BF_INSTALL_MODE}" == 'client' ]]; then
      # Only the bitfusion-analytics service is valid on the client side
      mv linux/common/bitfusion-analytics.service "${BF_OPT_DIR}/service/"; check_cmd "Error: failed to move the bitfusion-analytics.service file to ${BF_OPT_DIR}/service"
    else
      mv linux/common/bitfusion-*.service "${BF_OPT_DIR}/service/"; check_cmd "Error: failed to move the service files to ${BF_OPT_DIR}/service"
    fi
  else
    exit_log 8 "Could not install service files"
  fi

  if [[ -d lic ]]; then
    MOVE_LIC=1
    if [[ -d ${BF_ETC_DIR}/lic ]]; then
      REPLACE_LIC=0
      if [[ $BF_SILENT_INSTALL -eq 1 ]]; then
        report_log "i" "Overwriting existing license due to silent install"
        REPLACE_LIC=1
      else
        DONE=0
        while [[ $DONE -ne 1 ]]; do
          read -p "Do you want to replace the existing license with the embedded one? [y/n]: " -n 1 -r
          echo
          if [[ $REPLY =~ ^[Yy]$ ]]; then
            REPLACE_LIC=1
            DONE=1
          elif [[ $REPLY =~ ^[Nn]$ ]]; then
            report_log "i" "User leaving existing license in place"
            MOVE_LIC=0
            DONE=1
          else
            echo "Invalid response: ${REPLY}"
          fi
        done
      fi

      if [[ $REPLACE_LIC -eq 1 ]]; then
        rm -rf "${BF_ETC_DIR}/lic.bak"
        mv "${BF_ETC_DIR}/lic" "${BF_ETC_DIR}/lic.bak"
      fi
    fi

    if [[ $MOVE_LIC -eq 1 ]]; then
      report_log "i" "Installing embedded license"
      mv "lic/" "${BF_ETC_DIR}/"; check_cmd "Error: failed to move the license to ${BF_ETC_DIR}/"
    fi
  fi

  if [[ -x linux/common/bf_fpm_after_install.sh ]]; then
    if [[ $(id -u) -eq 0 ]]; then
      report_log "i" "Running post install script"
      linux/common/bf_fpm_after_install.sh; check_cmd "failed to run post install script"
    else
      report_log "i" "Skipping post install script because not root"
      echo "The post install script can only be run as root"
    fi
  else
    report_log "i" "Skipping post install script"
    echo "No post install script to run"
  fi

  # Only one service is allowed to run, so we return upon installing
  # one of them
  if [[ $BF_INSTALL_BFA_SERVICE -eq 1 ]]; then
    install_bitfusion_analytics_systemd_service
    report_log "i" "Bitfusion Analytics installation complete..."
    echo
    echo "Bitfusion Analytics installation complete..."
    return
  fi

  if [[ $BF_INSTALL_BFM_SERVICE -eq 1 ]]; then
    install_bitfusion_manager_systemd_service
    report_log "i" "Bitfusion Manager installation complete..."
    echo
    echo "Bitfusion Manager installation complete..."
    return
  fi

  if [[ $BF_INSTALL_SRS_SERVICE -eq 1 ]]; then
    install_bitfusion_srs_systemd_service
    report_log "i" "Bitfusion SRS installation complete..."
    echo
    echo "Bitfusion SRS installation complete..."
    return
  fi

  echo
  echo "To run a system health check do: bitfusion health"
  if [[ ! -f ${BF_ETC_DIR}/lic/license.txt ]]; then
    echo "To initialize your license do: sudo bitfusion init"
  fi

  echo
  echo "installation complete..."
}

#---  FUNCTION  --------------------------------------------------------------------------------------------------------
#          NAME:  usage
#   DESCRIPTION:  Function to display basic install help
#-----------------------------------------------------------------------------------------------------------------------
usage () {
  echo "usage: install [[-v version ] [-m mode ] [-d|D] [-s] [-u] | [-h]]"
  echo ""
  echo "  -v, --version; The version of Bitfusion you want to install"
  echo "  -s, --silentinstall; Do a silent or unattended install and accept the EULA"
  echo "  -u, --uninstall; Uninstall current version of Bitfusion (except license, configs and data)."
  echo "      Run with --purge to clean configs, logs, license, and historical data"
  echo "  -d, --deps; Install dependencies only"
  echo "  -D, --nodeps; Do not install dependencies"
  echo "  --list-deps; List dependencies for this version on FD (does not install them)"
  echo "  --list-missing-deps; List only missing dependencies for this version on FD (does not install them)"
  echo "  --overwrite; Overwrite any old versions"
  echo "  -m, --mode; Install mode (client/fda/server/srs/adaptor-only/server-only)"
  echo "  -h, --help; Display help"
  echo ""
}

uninstall() {
  if [[ $BF_SILENT_INSTALL -ne 1 ]]; then
    DONE=0
    while [[ $DONE -ne 1 ]]; do
      read -p "Are you sure you want to uninstall Bitfusion from the system? [y/n]: " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Nn]$ ]]; then
        exit_log 7 "Aborting uninstall"
      elif [[ $REPLY =~ ^[Yy]$ ]]; then
        DONE=1
      else
        echo "Invalid response: ${REPLY}"
      fi
    done
  fi

  report_log "i" "Uninstalling Bitfusion..."
  echo "Uninstalling Bitfusion..."

  if [ "$1" == "--purge" ] && [ -f "${BF_ETC_DIR}/lic/license.txt" ]; then
    report_log "i" "Deallocating existing license"

    if ! (sudo bitfusion dealloc) || [ -f "${BF_ETC_DIR}/lic/license.txt" ]; then
      echo "Warning! Could not deallocate existing license. It will just be removed."
      report_log "w" "Could not deallocate existing license. It will just be removed."
    fi
  fi

  clean_previous_install

  if [ "$1" == "--purge" ]; then
    report_log "i" "Removing ${BF_ETC_DIR}"
    rm -rf "${BF_ETC_DIR}"; check_cmd "Cannot remove ${BF_ETC_DIR}"
    report_log "i" "Removing ${BF_BASE_DIR}/var/run/bitfusion"
    rm -rf "${BF_BASE_DIR}/var/run/bitfusion"; check_cmd "Cannot remove ${BF_BASE_DIR}/var/run/bitfusion"
    report_log "i" "Removing ${BF_BASE_DIR}/var/lib/bitfusion"
    rm -rf "${BF_BASE_DIR}/var/lib/bitfusion"; check_cmd "Cannot remove ${BF_BASE_DIR}/var/lib/bitfusion"
    report_log "i" "Removing ${BF_HOME_PATH}/.bitfusion"
    rm -rf "${BF_HOME_PATH}/.bitfusion"; check_cmd "Cannot remove ${BF_HOME_PATH}/.bitfusion"
  fi

  if [[ -x ./linux/common/bf_fpm_after_remove.sh ]]; then
    linux/common/bf_fpm_after_remove.sh; check_cmd "failed to run post uninstall script"
    report_log "i" "Running post uninstall script"
  else
    echo "No post uninstall script to run"
    report_log "i" "Skipping post uninstall script"
  fi

  echo "Bitfusion uninstallation complete."
}


########################################################################################################################
#
# Install VMware Bitfusion
#
########################################################################################################################
create_install_log

# Unless we received the silent flag, figure out if we have a TTY
# available. If not we have to default to silent enabled
if [[ -z $BF_SILENT_INSTALL ]];then
  USE_TTY=""
  ! tty -s
  HAS_TTY=$?
  if [[ $HAS_TTY -ne 1 ]]; then
    report_log "i" "No TTY detected. Switching to silent installation"
    USE_TTY=""
    BF_SILENT_INSTALL=1
  else
    # Default for interactive or user install assumes you have a TTY.
    USE_TTY="</dev/tty"
    BF_SILENT_INSTALL=0
  fi
fi

if [[ "$1" == "" ]];then
  catch_uninstall_error
fi

select_os

while [ "$1" != "" ]; do
  case $1 in
    -b | --build )
      export BF_VERSION=$2
      shift
      ;;
    -v | --version )
      export BF_VERSION=$2
      shift
      ;;
    -m | --mode )
      export BF_INSTALL_MODE=$2
      shift
      ;;
    --deps)
      export BF_DEPS_ONLY="1"
      ;;
    --list-deps)
      list_bitfusion_deps
      exit
      ;;
    --list-missing-deps)
      list_bitfusion_missing_deps
      exit
      ;;
    --nodeps)
      export BF_NODEPS="1"
      ;;
    --overwrite)
      export BF_OVERWRITE=1
      ;;
    -u | --uninstall)
      uninstall "$2"
      exit
      ;;
    -s | --silentinstall )
      export BF_SILENT_INSTALL=1
      export USE_TTY=""
      ;;
    -h | --help )
      usage
      exit
      ;;
    * )
      usage
      exit 1
  esac
  shift
done

OLD_BF_OPT_LIB_DIR="${BF_BASE_DIR}${BF_OPT_LIB_DIR:-/opt/bitfusion/lib/${BF_INSTALL_ARCH}-linux-gnu/bitfusion}"
BF_OPT_LIB_DIR="${BF_BASE_DIR}${BF_OPT_LIB_DIR:-/opt/bitfusion/$BF_VERSION-$BF_SHORT_SHA/${BF_INSTALL_ARCH}-linux-gnu/}"
OLD_TO_NEW_OPT_LIB_SYMLINK=("../../${BF_VERSION}-${BF_SHORT_SHA}/${BF_INSTALL_ARCH}-linux-gnu" bitfusion)
SHA_ONLY_SYMLINK=("${BF_VERSION}-${BF_SHORT_SHA}" "${GIT_COMMIT}")
LATEST_SYMLINK=("${BF_VERSION}-${BF_SHORT_SHA}" latest)
# Use a function so that we can be protected against partial download
# when piping to bash
install_bitfusion
