#!/bin/bash

function provision_roks_help() {
  [[ -n "$1" ]] && echo_warning "$1"
  reset_colors
  cat << EOM
Usage:
  mas provision-roks [options]
Where ${COLOR_YELLOW}specified${TEXT_RESET} each option may also be defined by setting the appropriate environment variable.
When no options are specified on the command line, interactive-mode will be enabled by default.

IBMCloud Credentials (Required):
  -a, --apikey ${COLOR_YELLOW}IBMCLOUD_APIKEY${TEXT_RESET}                  IBMCloud API key

Cluster Configuration (Required):
  -r, --resource-group ${COLOR_YELLOW}IBMCLOUD_RESOURCEGROUP${TEXT_RESET}   IBMCloud resource group to deploy the cluster in
  -c, --cluster-name ${COLOR_YELLOW}CLUSTER_NAME${TEXT_RESET}               Name of the cluster to be provisioned
  -v, --ocp-version ${COLOR_YELLOW}OCP_VERSION${TEXT_RESET}                 OCP version to use (e.g 4.16_openshift)

Worker Node Configuration (Required):
      --worker-count ${COLOR_YELLOW}ROKS_WORKERS${TEXT_RESET}               Number of worker nodes to provision
      --worker-flavor ${COLOR_YELLOW}ROKS_FLAVOR${TEXT_RESET}               The flavour of worker node to use (e.g. b3c.16x64.300gb)
      --worker-zone ${COLOR_YELLOW}ROKS_ZONE${TEXT_RESET}                   IBM Cloud zone where the cluster should be provisioned. (e.g. dal10)

GPU Support (Optional):
      --gpu-worker-count ${COLOR_YELLOW}GPU_WORKERS${TEXT_RESET}            Number of GPU worker nodes to provision
      --gpu-workerpool-name ${COLOR_YELLOW}GPU_WORKERPOOL_NAME${TEXT_RESET} Name of the GPU workerpool

Storage Provisioner Configuration:
      --storage ${COLOR_YELLOW}OCP_STORAGE_PROVIDER${TEXT_RESET}            Choose optional storage provider (longhorn)

Turbonomic Integration:
      --turbonomic-name ${COLOR_YELLOW}TURBONOMIC_TARGET_NAME${TEXT_RESET}               Target name in Turbonomic
      --turbonomic-url ${COLOR_YELLOW}TURBONOMIC_SERVER_URL${TEXT_RESET}                 Turbonomic server URL
      --turbonomic-version ${COLOR_YELLOW}TURBONOMIC_SERVER_VERSION${TEXT_RESET}         Turbonomic server version
      --turbonomic-username ${COLOR_YELLOW}TURBONOMIC_USERNAME${TEXT_RESET}              Turbonomic username
      --turbonomic-password ${COLOR_YELLOW}TURBONOMIC_PASSWORD${TEXT_RESET}              Turbonomic password

Other Commands:
      --no-confirm                              Provision the cluster without prompting for confirmation
  -h, --help                                    Show this help message
EOM
  [[ -n "$1" ]] && exit 1 || exit 0
}

function provision_roks_noninteractive() {
  while [[ $# -gt 0 ]]
  do
    key="$1"
    shift
    case $key in
      -a|--apikey)
        IBMCLOUD_APIKEY=$1 && shift
        ;;
      -r|--resource-group)
        IBMCLOUD_RESOURCEGROUP=$1 && shift
        ;;
      -c|--cluster-name)
        CLUSTER_NAME=$1 && shift
        ;;
      -v|--ocp-version)
        OCP_VERSION=$1 && shift
        ;;
      --worker-count)
        ROKS_WORKERS=$1 && shift
        ;;
      --worker-flavor)
        ROKS_FLAVOR=$1 && shift
        ;;
      --worker-zone)
        ROKS_ZONE=$1 && shift
        ;;
      --gpu-worker-count)
        OCP_PROVISION_GPU=true
        GPU_WORKERS=$1 && shift
        ;;
      --gpu-workerpool-name)
        OCP_PROVISION_GPU=true
        GPU_WORKERPOOL_NAME=$1 && shift
        ;;

      # Storage Configuration
      --storage)
        OCP_STORAGE_PROVIDER=$1 && shift
        ;;
      --upgrade-registry-storage)
        UPGRADE_IMAGE_REGISTRY_STORAGE=true
        ;;

      # Turbonomic
      --turbonomic-name)
        TURBONOMIC_TARGET_NAME=$1 && shift
        ;;
      --turbonomic-url)
        TURBONOMIC_SERVER_URL=$1 && shift
        ;;
      --turbonomic-version)
        TURBONOMIC_SERVER_VERSION=$1 && shift
        ;;
      --turbonomic-username)
        TURBONOMIC_USERNAME=$1 && shift
        ;;
      --turbonomic-password)
        TURBONOMIC_PASSWORD=$1 && shift
        ;;

      # Other options
      --no-confirm)
        NO_CONFIRM=true
        ;;
      -h|--help)
        provision_roks_help
        ;;
      *)
        # unknown option
        echo -e "${COLOR_RED}Usage Error: Unsupported option \"${key}\"${TEXT_RESET}\n"
        provision_roks_help
        exit 1
        ;;
      esac
  done

  # Check all args have been set
  [[ -z "$IBMCLOUD_APIKEY" ]] && provision_roks_help "IBMCLOUD_APIKEY is not set"
  [[ -z "$IBMCLOUD_RESOURCEGROUP" ]] && provision_roks_help "IBMCLOUD_RESOURCEGROUP is not set"
  [[ -z "$CLUSTER_NAME" ]] && provision_roks_help "CLUSTER_NAME is not set"
  [[ -z "$OCP_VERSION" ]] && provision_roks_help "OCP_VERSION is not set"
  [[ -z "$ROKS_WORKERS" ]] && provision_roks_help "ROKS_WORKERS is not set"
  [[ -z "$ROKS_FLAVOR" ]] && provision_roks_help "ROKS_FLAVOR is not set"
  [[ -z "$ROKS_ZONE" ]] && provision_roks_help "ROKS_ZONE is not set"
}

function provision_roks_interactive() {

  echo_h2 "IBM Cloud API Key"
  echo "Provide your IBM Cloud API key (if you have not set the IBMCLOUD_APIKEY"
  echo "environment variable) which will be used to provision a ROKS instance."
  echo ""
  prompt_for_secret "IBM Cloud API Key" IBMCLOUD_APIKEY "Re-use saved IBM Cloud API Key?" && export IBMCLOUD_APIKEY

  echo ""
  echo_h2 "IBM Cloud ROKS Cluster Configuration"
  echo "Select your worker node flavour and the number of worker nodes to provision."
  echo "We recommend the 'b3c.16x64.300gb' worker node flavour to provide the best balance"
  echo "of performance, flexibility, and cost.  Three workers is sufficient to install"
  echo "all applications in the suite, but larger workloads will require more worker nodes."
  echo "You can easily add and remove worker nodes to the cluster after provision so do not"
  echo "worry too much if you are not sure how many worker nodes you need as this can "
  echo "easily be adjusted at any time to scale your cluster up or down."
  echo ""
  if [[ ! -z "$1" ]]; then
    CLUSTER_NAME=$1
  fi

  prompt_for_input "Cluster Name" CLUSTER_NAME && export CLUSTER_NAME
  export CLUSTER_TYPE=roks

  echo
  echo "OCP Version:"
  echo "  1. 4.19"
  echo "  2. 4.18"
  echo "  3. 4.17"
  echo "  4. 4.16"
  prompt_for_input "Select Version" OCP_VERSION_SELECTION "1"

  case $OCP_VERSION_SELECTION in
    1|4.19)
      export OCP_VERSION=4.19_openshift
      ;;
    2|4.18)
      export OCP_VERSION=4.18_openshift
      ;;
    3|4.17)
      export OCP_VERSION=4.17_openshift
      ;;
    4|4.16)
      export OCP_VERSION=4.16_openshift
      ;;

    *)
      export OCP_VERSION=$OCP_VERSION_SELECTION
      ;;
  esac

  prompt_for_input "Resource Group" IBMCLOUD_RESOURCEGROUP "Default" && export IBMCLOUD_RESOURCEGROUP
  prompt_for_input "Datacenter" ROKS_ZONE "dal10" && export ROKS_ZONE
  prompt_for_input "Worker Node Type" ROKS_FLAVOR "b3c.16x64.300gb" && export ROKS_FLAVOR
  prompt_for_input "Number of Worker Nodes" ROKS_WORKERS "3" && export ROKS_WORKERS

  export OCP_PROVISION_GPU=false
  echo ""
  echo_h2 "Bare Metal GPU Worker Support"
  echo "GPU worker nodes with flavour, mg4c.32x384.2xp100, can be added to the cluster"
  echo "for applications that require complex mathematical computations.  If you intnd"
  echo "to install the IBM Visual Inspection application you should answer 'yes' at"
  echo "the prompt below."
  echo ""
  prompt_for_confirm "Provision GPU worker nodes in cluster" && export OCP_PROVISION_GPU=true

  if [[ $OCP_PROVISION_GPU == "true" ]]; then
    prompt_for_input "Number of GPU Nodes" GPU_WORKERS "1" && export GPU_WORKERS
    prompt_for_input "GPU Worker Pool Name" GPU_WORKERPOOL_NAME "gpu" && export GPU_WORKERPOOL_NAME
  fi

  echo
  echo_h2 "Storage Provider:"
  echo "  1. IBMCloud"
  echo "  2. Longhorn"
  prompt_for_input "Select the storage provider to setup" OCP_STORAGE_PROVIDER_SELECTION "1"

  if [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "1" ]]; then
    OCP_STORAGE_PROVIDER=""
  elif [[ "$OCP_STORAGE_PROVIDER_SELECTION" == "2" ]]; then
    OCP_STORAGE_PROVIDER="longhorn"
  fi

  echo
  echo_h2 "Turbonomic Integration:"
  echo "Leave name empty if you do not want to enable Turbonomic integration in this cluster"
  prompt_for_input "Turbonomic Name" TURBONOMIC_TARGET_NAME
  if [[ "$TURBONOMIC_TARGET_NAME" != "" ]]; then
    prompt_for_input "Server URL" TURBONOMIC_SERVER_URL
    prompt_for_input "Server Version" TURBONOMIC_SERVER_VERSION
    prompt_for_input "Username" TURBONOMIC_USERNAME
    prompt_for_secret "Password" TURBONOMIC_PASSWORD
  fi

  export UPGRADE_IMAGE_REGISTRY_STORAGE=false
  echo ""
  echo_h2 "Upgrade Image Registry Capacity"
  echo "By default IBMCloud ROKS provisions 100GB of storage for the internal container registry."
  echo "Answer 'yes' at the prompt below to upgrade the storage capacity to 400GB."
  echo ""
  prompt_for_confirm "Upgrade Image Registry Storage from 100GB to 400GB" && export UPGRADE_IMAGE_REGISTRY_STORAGE=true

}


function provision_roks() {
  # Take the first parameter off (it will be provision-fyre)
  shift
  if [[ $# -gt 0 ]]; then
    provision_roks_noninteractive "$@"
  else
    provision_roks_interactive
  fi

  # Ensure all environment variables are available to ansible-playbook
  export IBMCLOUD_APIKEY
  export IBMCLOUD_RESOURCEGROUP

  export CLUSTER_TYPE=roks
  export CLUSTER_NAME
  export OCP_VERSION
  export ROKS_WORKERS
  export ROKS_FLAVOR
  export ROKS_ZONE
  export OCP_PROVISION_GPU
  export GPU_WORKERS
  export GPU_WORKERPOOL_NAME
  export UPGRADE_IMAGE_REGISTRY_STORAGE

  export OCP_STORAGE_PROVIDER

  export TURBONOMIC_TARGET_NAME
  export TURBONOMIC_SERVER_URL
  export TURBONOMIC_SERVER_VERSION
  export TURBONOMIC_USERNAME
  export TURBONOMIC_PASSWORD


  echo ""
  echo_h2 "Review Settings"

  echo "${TEXT_DIM}"
  echo_h2 "IBMCloud Authentication" "    "
  echo_reset_dim "IBMCloud Resource Group ... $IBMCLOUD_RESOURCEGROUP"

  reset_colors
  echo "${TEXT_DIM}"
  echo_h2 "Cluster Configuration" "    "
  echo_reset_dim "Cluster Name .............. $CLUSTER_NAME"
  echo_reset_dim "OCP Version ............... $OCP_VERSION"
  echo_reset_dim "Upgrade Registry Storage .. ${UPGRADE_IMAGE_REGISTRY_STORAGE:-false}"

  reset_colors
  echo "${TEXT_DIM}"
  echo_h2 "Worker Configuration" "    "
  echo_reset_dim "Worker Flavour ............ $ROKS_FLAVOR"
  echo_reset_dim "Worker Pool Zone .......... $ROKS_ZONE"
  echo_reset_dim "Worker Pool Size .......... $ROKS_WORKERS"
  echo_reset_dim "Add GPU Worker Nodes ...... ${OCP_PROVISION_GPU:-false}"
  if [[ $OCP_PROVISION_GPU == "true" ]]; then
    echo_reset_dim "GPU Worker Pool Size ...... $GPU_WORKERS"
    echo_reset_dim "GPU Worker Pool Name ...... $GPU_WORKERPOOL_NAME"
  fi

  reset_colors
  echo "${TEXT_DIM}"
  echo_h2 "Storage" "    "
  if [[ "${OCP_STORAGE_PROVIDER}" == "" ]]; then
    echo_reset_dim "Storage Provider ............ ${COLOR_MAGENTA}IBMCloud"
  else
    echo_reset_dim "Storage Provider ............ ${COLOR_MAGENTA}${OCP_STORAGE_PROVIDER}"
  fi

  if [[ "${TURBONOMIC_TARGET_NAME}" != "" ]]; then
    reset_colors
    echo "${TEXT_DIM}"
    echo_h2 "Turbonomic Integration" "    "
    echo_reset_dim "Target Name ................. ${COLOR_MAGENTA}${TURBONOMIC_TARGET_NAME}"
    echo_reset_dim "Server URL .................. ${COLOR_MAGENTA}${TURBONOMIC_SERVER_URL}"
    echo_reset_dim "Server Version .............. ${COLOR_MAGENTA}${TURBONOMIC_SERVER_VERSION}"
  fi

  echo
  reset_colors
  if [[ "$NO_CONFIRM" != "true" ]]; then
    prompt_for_confirm "Proceed with these settings" || exit 0
  fi

  ansible-playbook ibm.mas_devops.ocp_roks_provision || exit 1

  echo ""
  echo "IBM Cloud ROKS cluster is ready to use"
  OCP_CONSOLE_ROUTE=$(oc -n openshift-console get route console -o=jsonpath='{.spec.host}')
  echo "Connected to OCP cluster: https://$OCP_CONSOLE_ROUTE"
}
