#!/usr/bin/env bash
#
# Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# version 3 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 3 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#

# Shell wrapper for R executable.
# Manually adjusted version of what GNU-R/src/scripts/R.sh.in template would produce
# There is no copyright in the template, but it is a part GNU-R sources, see COPYING for details
# Modifications for FastR:
#  * find R_HOME_DIR from the location of this script
#  * use $R_HOME/bin/safe-forward-sed for SED
#  * forwarding FASTR_INTERNAL_ARGS, used internally in FastR to forward FastR options/flags to FastR subprocesses

# FastR patch: find R_HOME_DIR
source="${BASH_SOURCE[0]}"
while [ -h "$source" ] ; do
  prev_source="$source"
  source="$(readlink "$source")";
  if [[ "$source" != /* ]]; then
    # if the link was relative, it was relative to where it came from
    dir="$( cd -P "$( dirname "$prev_source" )" && pwd )"
    source="$dir/$source"
  fi
done
r_bin="$( cd -P "$( dirname "$source" )" && pwd )"
R_HOME_DIR="$( dirname "$r_bin" )"
# FastR patch: end

if test -n "${R_HOME}" && \
   test "${R_HOME}" != "${R_HOME_DIR}"; then
  echo "WARNING: ignoring environment value of R_HOME"
fi
R_HOME="${R_HOME_DIR}"
export R_HOME
R_SHARE_DIR="${R_HOME_DIR}/share"
export R_SHARE_DIR
R_INCLUDE_DIR="${R_HOME_DIR}/include"
export R_INCLUDE_DIR
R_DOC_DIR="${R_HOME_DIR}/doc"
export R_DOC_DIR

# Since this script can be called recursively, we allow R_ARCH to
# be overridden from the environment.
# This script is shared by parallel installs, so nothing in it should
# depend on the sub-architecture except the default here.
: ${R_ARCH=}

usage="
Usage: R [options] [< infile] [> outfile]
   or: R CMD command [arguments]

Start R, a system for statistical computation and graphics, with the
specified options, or invoke an R tool via the 'R CMD' interface.

Options:
  -h, --help            Print short help message and exit
  --version             Print version info and exit
  --encoding=ENC        Specify encoding to be used for stdin
  --encoding ENC
  RHOME			Print path to R home directory and exit
  --save                Do save workspace at the end of the session
  --no-save             Don't save it
  --no-environ          Don't read the site and user environment files
  --no-site-file        Don't read the site-wide Rprofile
  --no-init-file        Don't read the user R profile
  --restore             Do restore previously saved objects at startup
  --no-restore-data     Don't restore previously saved objects
  --no-restore-history  Don't restore the R history file
  --no-restore          Don't restore anything
  --vanilla		Combine --no-save, --no-restore, --no-site-file,
			--no-init-file and --no-environ
  --no-readline         Don't use readline for command-line editing
  --max-ppsize=N        Set max size of protect stack to N
  --min-nsize=N         Set min number of fixed size obj's (\"cons cells\") to N
  --min-vsize=N         Set vector heap minimum to N bytes; '4M' = 4 MegaB
  -q, --quiet           Don't print startup message
  --silent              Same as --quiet
  -s, --no-echo         Make R run as quietly as possible
  --interactive         Force an interactive session
  --verbose             Print more information about progress
  -d, --debugger=NAME   Run R through debugger NAME
  --debugger-args=ARGS  Pass ARGS as arguments to the debugger
  -g TYPE, --gui=TYPE	Use TYPE as GUI; possible values are 'X11' (default)
			and 'Tk'.
  --arch=NAME		Specify a sub-architecture
  --args                Skip the rest of the command line
  -f FILE, --file=FILE  Take input from 'FILE'
  -e EXPR               Execute 'EXPR' and exit

FILE may contain spaces but not shell metacharacters.

Commands:
  BATCH			Run R in batch mode
  COMPILE		Compile files for use with R
  SHLIB			Build shared library for dynamic loading
  INSTALL		Install add-on packages
  REMOVE		Remove add-on packages
  build			Build add-on packages
  check			Check add-on packages
  LINK			Front-end for creating executable programs
  Rprof			Post-process R profiling files
  Rdconv		Convert Rd format to various other formats
  Rd2pdf		Convert Rd format to PDF
  Rd2txt		Convert Rd format to pretty text
  Stangle		Extract S/R code from Sweave documentation
  Sweave		Process Sweave documentation
  Rdiff			Diff R output ignoring headers etc
  config		Obtain configuration information about R
  javareconf		Update the Java configuration variables
  rtags                 Create Emacs-style tag files from C, R, and Rd files

Please use 'R CMD command --help' to obtain further information about
the usage of 'command'.

Options --arch, --no-environ, --no-init-file, --no-site-file and --vanilla
can be placed between R and CMD, to apply to R processes run by 'command'

Report bugs at <https://bugs.R-project.org>."

## some systems have a more portable sed, e.g. /usr/xpg4/bin/sed on Solaris,
## so make sure that is used.
SED=$R_HOME/bin/safe-forward-sed
export SED

error () {
  echo "ERROR: $*" >&2
  exit 1
}

### Argument loop
args=
debugger=
debugger_args=
gui=
while test -n "${1}"; do
  case ${1} in
    RHOME|--print-home)
      echo "${R_HOME}"; exit 0 ;;
    CMD)
      shift;
      export R_ARCH
      . "${R_HOME}/etc${R_ARCH}/ldpaths"
      FASTR_INTERNAL_ARGS=`echo "${FASTR_INTERNAL_ARGS} ${args}" | ${SED} -e s/^[[:space:]]*// | ${SED} -e s/[[:blank:]]*$//` exec sh "${R_HOME}/bin/Rcmd" "${@}" ;;
    -g|--gui)
      if test -n "`echo ${2} | ${SED} 's/^-.*//'`"; then
	gui="${2}"
        args="${args} ${1} ${2}"
	shift
      else
	error "option '${1}' requires an argument"
      fi
      ;;
    --gui=*)
      gui=`echo "${1}" | ${SED} -e 's/[^=]*=//'`
      args="${args} ${1}"
      ;;
    -d|--debugger)
      if test -n "`echo ${2} | ${SED} 's/^-.*//'`"; then
	debugger="${2}"; shift
      else
	error "option '${1}' requires an argument"
      fi
      ;;
    --debugger=*)
      debugger=`echo "${1}" | ${SED} -e 's/[^=]*=//'` ;;
    --debugger-args=*)
      debugger_args=`echo "${1}" | ${SED} -e 's/[^=]*=//'` ;;
    --r-help)
      echo "${usage}"; exit 0 ;;
    --args)
      break ;;
    --arch)
      if test -n "`echo ${2} | ${SED} 's/^-.*//'`"; then
	R_ARCH="/${2}"
        shift
      else
        error "option '${1}' requires an argument"
      fi
      ## check sub-architecture here for a better error message
      if ! test -d ${R_HOME}/etc${R_ARCH}; then
        error "sub-architecture '${1}' is not installed"
      fi
      ;;
    --arch=*)
      r_arch=`echo "${1}" | ${SED} -e 's/[^=]*=//'`
      R_ARCH="/${r_arch}"
      ## check sub-architecture here for a better error message
      if ! test -d ${R_HOME}/etc${R_ARCH}; then
        error "sub-architecture '${r_arch}' is not installed"
      fi
      ;;
    -e)
      if test -n "`echo ${2} | ${SED} 's/^-.*//'`"; then
	a=`(echo "${2}" && echo) | ${SED} -e 's/ /~+~/g' | \
          ${SED} -e :a -e N -e '$!ba' -e 's/\n/~n~/g' -e 's/~n~$//g'`
        shift
      else
	error "option '${1}' requires a non-empty argument"
      fi
      args="${args} -e $a"
      ;;
    -f)
      if test -n "`echo ${2} | ${SED} 's/^-.*//'`"; then
	a=`echo "${2}" | ${SED} -e 's/ /~+~/g'`; shift
      else
	error "option '${1}' requires a filename argument"
      fi
      args="${args} -f $a"
      ;;
    --file=*)
      a=`echo "${1}" | ${SED} -e 's/[^=]*=//' | ${SED} -e 's/ /~+~/g'`
      args="${args} --file=$a"
      ;;
    --no-environ)
      export R_ENVIRON=''
      export R_ENVIRON_USER=''
      args="${args} ${1}"
      ;;
    --no-site-file)
      export R_PROFILE=''
      args="${args} ${1}"
      ;;
    --no-init-file)
      export R_PROFILE_USER=''
      args="${args} ${1}"
      ;;
    --vanilla)
      export R_ENVIRON=''
      export R_ENVIRON_USER=''
      export R_PROFILE=''
      export R_PROFILE_USER=''
      args="${args} ${1}"
      ;;
    *)
      args="${args} ${1}" ;;
  esac
  shift
done

. "${R_HOME}/etc${R_ARCH}/ldpaths"

R_binary="${R_HOME}/bin/exec${R_ARCH}/R"
export R_ARCH

case "${gui}" in
Tk|tk|X11|x11)
  ;;
"")
  ;;
*)
  error "unknown GUI ${gui}"
esac

## R_HOME may have moved, so check
if test -x "${R_HOME}"; then
  :
else
  error "R_HOME ('${R_HOME}') not found"
fi

## Startup
if test -z "${debugger}"; then
  exec "${R_binary}"  ${args} "${@}"
else
  ## Ideally, we would like the debugger to start R with additional
  ## ('inferior') arguments, but not all debuggers can do this.  We know
  ## about valgrind and some versions of GDB , and deal with these.
  ## Otherwise, to be on the safe side, we disregard non-debugger
  ## command line args.
  args_ok=no
  case "`${debugger} --version 2>/dev/null`" in
    "GNU gdb"*)
      if ${debugger} --help 2>/dev/null | \
          grep ' *--args' >/dev/null; then
	args_ok=yes
	debugger_args="${debugger_args} --args"
      fi
      ;;
    valgrind*)
      args_ok=yes
      ;;
  esac
  if test -n "${args}${*}" && test "${args_ok}" = no; then
    args=`expr "${args} ${*}" : " *\(.*\)"`
    echo "*** Further command line arguments ('${args}') disregarded"
    echo "*** (maybe use 'run ${args}' from *inside* ${debugger})"
    echo ""
    exec ${debugger} ${debugger_args} "${R_binary}"
  else
    exec ${debugger} ${debugger_args} "${R_binary}" ${args} "${@}"
  fi
fi

### Local Variables: ***
### mode: sh ***
### sh-indentation: 2 ***
### End: ***
