#!/bin/bash

SOURCE="${BASH_SOURCE[0]}"

# resolve $SOURCE until the file is no longer a symlink
while [ -h "$SOURCE" ]; do
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"


ML_SERVER_ROOT=$(cd "${SCRIPT_DIR}/../.."; pwd -P)
ML_SERVER_VERSION=$(basename $(dirname ${SCRIPT_DIR}))

export R_LIBS=${ML_SERVER_ROOT}/libraries/RServer

# if running in Parcels, load extra config and run extra prepartory logic
if [ -e "${SCRIPT_DIR}/../Revo-init" ] ; then
  source "${SCRIPT_DIR}/../Revo-init"
fi


function start_r()
{
  exec ${ML_SERVER_ROOT}/runtime/R/bin/R "$@"
}

function setup_runtime()
{
    local expected_runtime=$(cat ${SCRIPT_DIR}/DEFAULT_RUNTIME)
    local r_path="/opt/microsoft/ropen/${expected_runtime}/lib64/R"
    
    if [[ -d ${ML_SERVER_ROOT}/runtime/R ]]; then
        return 0
    fi

    if [[ $(id -u) -ne 0 ]]; then
      echo "FATAL: Sudo or Root permissions are needed to setup the runtime"
      return 1
    fi

    if [[ ! -d ${ML_SERVER_ROOT}/runtime ]]; then
      mkdir ${ML_SERVER_ROOT}/runtime
    fi

    if [[ $# -ne 0 ]]; then
      r_path=$1
    fi

    echo "INFO: Searching for runtime at ${r_path}"
    if [[ -d ${r_path} ]]; then
      echo "INFO: Found R runtime at ${r_path}"
      echo "INFO: Setting up R Runtime"
      cp -r ${r_path} ${ML_SERVER_ROOT}/runtime/R
      return 0
    else
      echo "FATAL: Could not find a sutable default R runtime. Please ensure Microsoft R Open ${EXPECTED_RUNTIME} is installed"
      return 1
    fi
}

function unlink_runtime()
{
  if [[ $(id -u) -ne 0 ]]; then
    echo "FATAL: Sudo or Root permissions are needed to unlink the runtime"
    return 1
  fi

  rm -rf ${ML_SERVER_ROOT}/runtime/R

  local ret=$?

  rmdir ${ML_SERVER_ROOT}/runtime 2> /dev/null

  return ${ret}
}

function symlink_mlserver()
{
  if [[ $(id -u) -ne 0 ]]; then
    echo "FATAL: Sudo or Root permissions are needed to setup symlinks"
    return 1
  fi

  local expected_runtime=$(cat ${SCRIPT_DIR}/DEFAULT_RUNTIME)
  local r_path="/opt/microsoft/ropen/${expected_runtime}/lib64/R/bin/R"
  local rscript_path="/opt/microsoft/ropen/${expected_runtime}/lib64/R/bin/Rscript"

  if [[ -f /usr/bin/R ]]; then
    local r_link=$(readlink -f /usr/bin/R)
    echo "Found /usr/bin/R => ${r_link}"
    if [[ ${r_link} == ${r_path} ]]; then
      echo "Replacing /usr/bin/R with ${SCRIPT_DIR}/R"
      rm /usr/bin/R
      ln -s ${SCRIPT_DIR}/R /usr/bin/R
    fi
  fi
  
  if [[ -f /usr/bin/Rscript ]]; then
    local rscript_link=$(readlink -f /usr/bin/Rscript)
    echo "Found /usr/bin/Rscript => ${rscript_link}"
    if [[ ${rscript_link} == ${rscript_path} ]]; then
      echo "Replacing /usr/bin/Rscript with ${SCRIPT_DIR}/Rscript"
      rm /usr/bin/Rscript
      ln -s ${SCRIPT_DIR}/Rscript /usr/bin/Rscript
    fi
  fi

  if [[ -f /usr/bin/mlserver-R-${ML_SERVER_VERSION} ]]; then
    rm /usr/bin/mlserver-R-${ML_SERVER_VERSION}
  fi

  ln -s "${SCRIPT_DIR}/R" "/usr/bin/mlserver-R-${ML_SERVER_VERSION}"

  if [[ -f /usr/bin/mlserver-Rscript-${ML_SERVER_VERSION} ]]; then
    rm /usr/bin/mlserver-Rscript-${ML_SERVER_VERSION}
  fi

  ln -s "${SCRIPT_DIR}/Rscript" "/usr/bin/mlserver-Rscript-${ML_SERVER_VERSION}"
}

function unsymlink_mlserver()
{
  if [[ $(id -u) -ne 0 ]]; then
    echo "FATAL: Sudo or Root permissions are needed to unlink mlserver"
    return 1
  fi

  local expected_runtime=$(cat ${SCRIPT_DIR}/DEFAULT_RUNTIME)
  local r_path="/opt/microsoft/ropen/${expected_runtime}/lib64/R/bin/R"
  local r_script_path="/opt/microsoft/ropen/${expected_runtime}/lib64/R/bin/Rscript"

  if [[ -f /usr/bin/R ]]; then
    local r_link=$(readlink -f /usr/bin/R)
    echo "Found /usr/bin/R => ${r_link}"
    if [[ ${r_link} == ${SCRIPT_DIR}/R ]]; then
      echo "Replacing /usr/bin/R with ${r_path}"
      rm /usr/bin/R
      ln -s ${r_path} /usr/bin/R
    fi
  fi

  if [[ -f /usr/bin/Rscript ]]; then
    local r_script_link=$(readlink -f /usr/bin/Rscript)
    echo "Found /usr/bin/Rscript => ${r_script_link}"
    if [[ ${r_script_link} == ${SCRIPT_DIR}/Rscript ]]; then
      echo "Replacing /usr/bin/Rscript with ${r_script_path}"
      rm /usr/bin/Rscript
      ln -s ${r_script_path} /usr/bin/Rscript
    fi
  fi

  if [[ -f /usr/bin/mlserver-R-${ML_SERVER_VERSION} ]]; then
    rm /usr/bin/mlserver-R-${ML_SERVER_VERSION}
  fi


  if [[ -f /usr/bin/mlserver-Rscript-${ML_SERVER_VERSION} ]]; then
    rm /usr/bin/mlserver-Rscript-${ML_SERVER_VERSION}
  fi
}

if [[ $# -gt 0 ]]; then
  if [[ "$1" == "--mlserver-setup-runtime" ]]; then
    setup_runtime
    exit $?
  elif [[ "$1" == "--mlserver-unlink-runtime" ]]; then
    unlink_runtime
    exit $?
  elif [[ "$1" == "--mlserver-symlink" ]]; then
    symlink_mlserver
    exit $?
  elif [[ "$1" == "--mlserver-unsymlink" ]]; then
    unsymlink_mlserver
    exit $?
  fi
fi

if [[ -f ${ML_SERVER_ROOT}/runtime/R/bin/R ]]; then
  start_r "$@"
else
  echo "WARNING: No R Runtime configured"
  setup_runtime
  SETUP_RESULT=$?
  if [[ ${SETUP_RESULT} -ne 0 ]]; then
    exit ${SETUP_RESULT}
  else
   start_r "$@"
  fi
fi
