#!/bin/bash #


# "Get Fleek Network" is an attempt to make our software more accessible.
# By providing scripts to automate the installation process of our software,
# we believe that it can help improve the onboarding experience of our users.
#
# Quick install: `curl https://get.fleek.network | bash`
#
# This script automates the process illustrated in our install documentation and guides,
# advanced users might find it better to follow the instructions in the documentation site.
# If that's your preference, go ahead and check our guides https://docs.fleek.network
#
# Contributing?
# - If you'd like to test changes locally based on a Lightning repo branch use the env var `USE_LIGHTNING_BRANCH`
# - If you'd like to test changes locally based on a get.fleek.network repo branch use the env var `USE_GET_BRANCH`
# E.g. curl https://raw.githubusercontent.com/fleek-network/get.fleek.network/feat/foobar-foo-bar/install | USE_GET_BRANCH="feat/foobar-foo-bar" bash
#
# Found an issue? Please report it here: https://github.com/fleek-network/get.fleek.network

# TODO: Switch to main on release
defaultBranch="testnet-internal"
useBranch=${USE_LIGHTNING_BRANCH="$defaultBranch"}
useGetBranch=${USE_GET_BRANCH="main"}

# Workdir
if ! cd "$(mktemp -d)"; then
  echo "šŸ‘¹ Oops! We tried to create a temporary directory to host some install artifacts but failed for some reason..."

  exit 1
fi

# Defaults
defaultTestInstallMagicWord=I_AM_FULLY_AWARE_AND_WANT_TO_PROCEED_TO_TEST_INSTALL_ONLY
defaultMenuOptionInstall="šŸ¤– Install"
defaultMenuOptionUtils="āš™ļø Tools"
defaultMenuOptionQuit="šŸ‘» Quit"
defaultMenuOptionNative="šŸ”« Natively (recommended)"
defaultMenuOptionDocker="šŸ‘¾ Docker (unstable)"
defaultMenuOptionHealthCheck="šŸš‘ Health check"
defaultMenuOptionNodeDetails="šŸŽ® Node details"
defaultMenuOptionUpdate="šŸ“¢ Node Update"
defaultMenuOptionServerDetails="šŸ“ø Server details"
defaultMenuOptionShutdown="šŸ’¤ Shutdown"
defaultScriptNameHealthCheck="healthcheck"
defaultScriptNameNodeDetails="node_details"
defaultScriptNameUpdate="update"
defaultScriptNameInstallNative="install_native"
defaultScriptNameInstallDocker="install_docker"
defaultScriptNameServerDetails="server_details"
defaultScriptNameShutdown="shutdown"

# Utils
testnetPhaseFinishedWarning() {
  echo "āš ļø WARNING: The Testnet Phase {1} has ENDED on Thursday, Oct. 26th 2023! You'll HAVE TO WAIT for next Testnet Phase in order to run a node successfully. If you'd like TO PARTICIPATE on the next phase, keep track of our announcements by following us on Discord and Twitter to avoid disappointment!"
  echo
  echo "If you decide to set up a node for testing the INSTALL PROCESS ONLY, knowing that it'll fail to run successfully, you can do so by typing $defaultTestInstallMagicWord in the prompt."
  echo

  while read -rp "šŸ™‹ā€ā™€ļø What do you have to type to proceed with the installation only? " answer; do
    if [[ "$answer" == "$defaultTestInstallMagicWord" ]]; then
      echo
      read -rp "āš ļø WARNING: The installer will now proceed. Remember that the node will NOT RUN SUCCESSFULLY as you have to wait for the new Testnet Phase announcement and rules. If you keep the setup, the future Testnet Phase will require you to update or troubleshoot it! Press ENTER to continue..."
      echo

      break;
    fi

    echo
    echo "šŸ’© Uh-oh! Seems that you haven't read the warning message. Exited!"
    echo

    exit 1
  done
}

menuTopLevel() {
  PS3=$'\nšŸ™ Please enter your choice: \n'
  options=("$defaultMenuOptionInstall" "$defaultMenuOptionUtils" "$defaultMenuOptionQuit")
  selected=""
  select opt in "${options[@]}"; do
      case $opt in
          "$defaultMenuOptionInstall")
              selected="$defaultMenuOptionInstall"

              break
              ;;
          "$defaultMenuOptionUtils")
              selected="$defaultMenuOptionUtils"

              break
              ;;
          "$defaultMenuOptionQuit")
              selected="$defaultMenuOptionQuit"

              break
              ;;
          *) echo "šŸ‘¹ Oop! Invalid option $REPLY, try again...";;
      esac
  done

  echo "$selected"
}

menuInstall() {
  PS3=$'\nšŸ™ Please enter your choice: \n'
  options=("$defaultMenuOptionNative" "$defaultMenuOptionDocker" "$defaultMenuOptionQuit")

  select opt in "${options[@]}"; do
      case $opt in
          "$defaultMenuOptionNative")
              selected="$defaultMenuOptionNative"

              break
              ;;
          "$defaultMenuOptionDocker")
              selected="$defaultMenuOptionDocker"

              break
              ;;
          "$defaultMenuOptionQuit")
              selected="$defaultMenuOptionQuit"

              break
              ;;
          *) echo "šŸ‘¹ Oop! Invalid option $REPLY, try again...";;
      esac
  done

  echo "$selected"
}

menuUtils() {
  PS3=$'\nšŸ™ Please enter your choice: \n'
  options=("$defaultMenuOptionHealthCheck" "$defaultMenuOptionNodeDetails" "$defaultMenuOptionUpdate" "$defaultMenuOptionServerDetails" "$defaultMenuOptionShutdown" "$defaultMenuOptionQuit")
  selected=""

  select opt in "${options[@]}"; do
      case $opt in
          "$defaultMenuOptionHealthCheck")
              selected="$defaultMenuOptionHealthCheck"

              break
              ;;
          "$defaultMenuOptionNodeDetails")
              selected="$defaultMenuOptionNodeDetails"

              break
              ;;
          "$defaultMenuOptionUpdate")
              selected="$defaultMenuOptionUpdate"

              break
              ;;
          "$defaultMenuOptionServerDetails")
              selected="$defaultMenuOptionServerDetails"

              break
              ;;
          "$defaultMenuOptionShutdown")
              selected="$defaultMenuOptionShutdown"

              break
              ;;
          "$defaultMenuOptionQuit")
              selected="$defaultMenuOptionQuit"

              break
              ;;
          *) echo "šŸ‘¹ Oop! Invalid option $REPLY, try again...";;
      esac
  done

  echo "$selected"
}

quitProcess() {
  printf "\n\nšŸ¦– The get.fleek.network process has terminated!\n\n"
  exit 1
}

runScriptByName() {
  curl -s "https://raw.githubusercontent.com/fleek-network/get.fleek.network/$useGetBranch/scripts/$1" > "$1"
  chmod +x "$1"

  ./"$1"
}

# The white space before and after is intentional
cat << "ART"

  ā­ļø Get! Fleek Network ā­ļø

              zeeeeee-
              z$$$$$$"
            d$$$$$$"
            d$$$$$P
          d$$$$$P
          $$$$$$"
        .$$$$$$"
      .$$$$$$"
      4$$$$$$$$$$$$$"
    z$$$$$$$$$$$$$"
    """""""3$$$$$"
          z$$$$P
          d$$$$"
        .$$$$$"
      z$$$$$"
      z$$$$P
    d$$$$$$$$$$"
    *******$$$"
        .$$$"
        .$$"
      4$P"
      z$"
    zP
    z"
  /

ART

(
  trap quitProcess INT

  exec < /dev/tty;

  if ! lscpu |  grep -q 'GenuineIntel'; then
    echo "āš ļø WARNING: The Fleek Network node binary is only supported on CPUs that adhere to the x86_64 architecture but mainly supporting GenuineIntel, as there's been reports of failure on AMD. ARM64 is not supported, but efforts have been put to support it. To learn more read the requirements section in https://docs.fleek.network/docs/node/requirements."
    read -rp "Press ENTER to continue..."
    echo
    echo
  fi

  echo "šŸ‘‹ The following menu provides you access to the installation process of a node, or the diagnostic and utility tools."
  echo

  selected=$(menuTopLevel)

  echo

  if [[ "$selected" == "$defaultMenuOptionInstall" ]]; then
    testnetPhaseFinishedWarning

    echo "šŸ‘‰ To install a node, choose between building it natively, or running as a docker container. The native install builds the binary from source-code, while the docker container is an instance of a prebuilt image."
    echo

    selected=$(menuInstall)
  elif [[ "$selected" == "$defaultMenuOptionUtils" ]]; then
    echo "šŸ‘‰ The tools gives you access to a set of diagnostic processes to help you assess information about your node, e.g. health checks, details, etc."
    echo

    selected=$(menuUtils)
  elif [[ "$selected" == "$defaultMenuOptionQuit" ]]; then
    quitProcess
  fi

  echo
  
  if [[ "$selected" == "$defaultMenuOptionNative" ]]; then
    echo
    echo "Before we launch the process, just to let you know that the Lightning CLI will be compiled from the Rust šŸ¦€ source code. Depending on your machine specifications this can be quite slow, be patient!"
    echo
    read -rp "Let's launch the process, press ENTER to continue..."

    runScriptByName "$defaultScriptNameInstallNative"
  elif [[ "$selected" == "$defaultMenuOptionDocker" ]]; then
    echo
    read -rp "We'll launch the Docker install process, press ENTER to continue..."

    runScriptByName "$defaultScriptNameInstallDocker"
  elif [[ "$selected" == "$defaultMenuOptionHealthCheck" ]]; then
    runScriptByName "$defaultScriptNameHealthCheck"
  elif [[ "$selected" == "$defaultMenuOptionNodeDetails" ]]; then
    runScriptByName "$defaultScriptNameNodeDetails"
  elif [[ "$selected" == "$defaultMenuOptionUpdate" ]]; then
    runScriptByName "$defaultScriptNameUpdate"
  elif [[ "$selected" == "$defaultMenuOptionServerDetails" ]]; then
    runScriptByName "$defaultScriptNameServerDetails"
  elif [[ "$selected" == "$defaultMenuOptionShutdown" ]]; then
    runScriptByName "$defaultScriptNameShutdown"
  fi
)