#!/bin/bash

source $(dirname $0)/shared-run

getDiagnosticSessionRedirection()
{
   if [[ -n "${POSITRON_DIAGNOSTICS_ENABLED}" ]]; then
      echo "|& tee -a $POSITRON_DIAGNOSTICS_FILE"
   else
      echo ""
   fi
}

getDiagnosticsPrintenv()
{
   if [[ -n "${POSITRON_DIAGNOSTICS_ENABLED}" ]]; then
      echo "echo -e \"[$(date)] ---- launching positron process ----\n[$(date)] ---- final env ----\n[$(date)] $(printenv)\" $(getDiagnosticSessionRedirection) &&"
   else
      echo ""
   fi
}

emitDiagnostic()
{
   if [[ -n "${POSITRON_DIAGNOSTICS_ENABLED}" ]]; then
      if ! echo "[$(date)] $1" >> $POSITRON_DIAGNOSTICS_FILE ; then
         echo "Error: $$ trying to append to $POSITRON_DIAGNOSTICS_FILE - turning off session diagnostics"
         POSITRON_DIAGNOSTICS_ENABLED=
      fi
   fi
}

getDiagnosticSessionStraceEnabled()
{
   if [[ -z "${POSITRON_DIAGNOSTICS_STRACE_ENABLED}" ]]; then
      echo "strace not enabled for this diagnostics report"
   elif command -v strace &> /dev/null; then
      echo "strace enabled for this diagnostics report"
      echo "strace report location: $POSITRON_STRACE_FILE"
      echo ""
   else
      echo "strace is not installed; cannot generate strace diagnostics"
   fi
}

getDiagnosticSessionStrace()
{
   if [[ -z "${POSITRON_DIAGNOSTICS_STRACE_ENABLED}" ]]; then
      echo ""
   elif command -v strace &> /dev/null; then
      echo "strace -fttTy -o $POSITRON_STRACE_FILE"
   else
      echo ""
   fi
}

runHooks "start"

# determine the config directory
if [ "$RSTUDIO_CONFIG_DIR" != "" ] ; then
   configDirs="$RSTUDIO_CONFIG_DIR"
else
   configDirs="$XDG_CONFIG_DIRS:/etc"
fi

IFS=':' read -ra configDirList <<< "$configDirs"
for configDir in "${configDirList[@]}"
do
   if test -e "$configDir/rstudio/positron.conf"
   then
      configFile="$configDir/rstudio/positron.conf"
      break
   fi
done

# load positron-profile script
if test -e "$configDir/rstudio/positron-profile"
then
   . "$configDir/rstudio/positron-profile"
fi

# session arguments
# escape backslashes in arguments to pass safely to bash below
POSITRON_ARGS="${@//\\/\\\\}"
RS_POSITRON_USER_EXT=${RS_POSITRON_USER_EXT:-0}

USER_DATA_HOME=${XDG_DATA_HOME:-${HOME}/.local/share}

# Allow individual users to enable session diagnostics to their local log directory
USER_DIAG_CONFIG="$HOME/.config/pwb/positron-diagnostics"
USER_DIAG_LOG_DIR="$USER_DATA_HOME/pwb/log"
if [[ -f "$USER_DIAG_CONFIG" ]] ; then
   USER_DIAG_MODE=$(cat "$USER_DIAG_CONFIG")
   if [[ "$USER_DIAG_MODE" =~ debug|strace ]] ; then
      export POSITRON_DIAGNOSTICS_ENABLED=true
      mkdir -p "$USER_DIAG_LOG_DIR"
      export POSITRON_DIAGNOSTICS_FILE="$USER_DIAG_LOG_DIR/positron-diagnostics.log"
      POSITRON_STRACE_FILE="${POSITRON_DIAGNOSTICS_FILE}.strace"
      if [[ "$USER_DIAG_MODE" = "strace" ]] ; then
         export POSITRON_DIAGNOSTICS_STRACE_ENABLED=true
      fi
      if [[ "$POSITRON_EXEC_COMMAND" =~ .*positron-server* ]] ; then
         LOG_PATTERN="--log"
         LOG_ARG="--log trace"
         LOG_DIR="$HOME/.positron-server/data/logs"
      fi

      if [[ ! "$POSITRON_ARGS" =~ .*"$LOG_PATTERN".* ]] ; then 
         POSITRON_ARGS="$POSITRON_ARGS $LOG_ARG"
      fi
      echo "Enabling $USER_DIAG_MODE diagnostics from config file $USER_DIAG_CONFIG" 
      echo "Diag files: $POSITRON_DIAGNOSTICS_FILE + .strace"
      echo "Debug logs: $LOG_DIR"
   elif [[ "$USER_DIAG_MODE" != "off" ]] ; then
      echo "Ignoring invalid session-diagnostics value: $USER_DIAG_MODE for file: $USER_DIAG_CONFIG - use one of strace, debug or off"
   fi
fi

# install positron extensions
if [ $RS_POSITRON_USER_EXT -eq 1 ]
then
   if [ -f /usr/lib/rstudio-server/extras/scripts/install-positron-ext.sh ]
   then
      POSITRON_EXEC_COMMAND=$POSITRON_EXEC_COMMAND POSITRON_ARGS=$POSITRON_ARGS /usr/lib/rstudio-server/extras/scripts/install-positron-ext.sh
   else
     echo "Skipping Positron extension updates because /usr/lib/rstudio-server/extras/scripts/install-positron-ext.sh was not found."
   fi
fi

if [[ -n "${RS_SESSION_SSL_CERT}" ]]; then
   if [[ -z "${RS_SESSION_SSL_CERT_KEY}" ]]; then
      echo "Error - public key without private key"
      exit 10
   fi

   CERT_DIR="/tmp/pwb-${USER}"
   mkdir -m 700 -p "${CERT_DIR}"

   CERT_ID=$(date +%s.%N)
   CERT_FILE="${CERT_DIR}/cert-${CERT_ID}.pem"
   KEY_FILE="${CERT_DIR}/key-${CERT_ID}.pem"
   rm -f ${CERT_FILE} ${KEY_FILE}
   (umask 077;
    echo "${RS_SESSION_SSL_CERT}" > "${CERT_FILE}";
    echo "${RS_SESSION_SSL_CERT_KEY}" > "${KEY_FILE}")
   POSITRON_ARGS="${POSITRON_ARGS} --cert ${CERT_FILE} --cert-key ${KEY_FILE}"
elif [[ -n "${RS_SESSION_SSL_CERT_PATH}" ]] ; then
   # eval variables like $HOME and $USER in RS_SESSION_CERT_PATH
   eval CERT_PATH=`echo ${RS_SESSION_SSL_CERT_PATH}`
   eval KEY_PATH=`echo ${RS_SESSION_SSL_CERT_KEY_PATH}`
   POSITRON_ARGS="${POSITRON_ARGS} --cert ${CERT_PATH} --cert-key ${KEY_PATH}"
fi

# dump user information
emitDiagnostic "---- user ---- "
emitDiagnostic "$(whoami)"

# dump initial environment
emitDiagnostic "---- init env ----"
emitDiagnostic "$(printenv)"

emitDiagnostic "Running session: ${POSITRON_EXEC_COMMAND} ${POSITRON_ARGS}"

echo "Running session: ${POSITRON_EXEC_COMMAND} ${POSITRON_ARGS}"

# SIGTERM is used to stop the session - so the hooks need to be run as a trap
trap 'runHooks "stop"' SIGTERM

# run the session
/bin/bash --login $POSITRON_PROFILE_OPTIONS -c "$(getDiagnosticsPrintenv) $(getDiagnosticSessionStrace) $POSITRON_EXEC_COMMAND $POSITRON_ARGS"

# store exit code of command
EXIT_CODE=$?

if [[ -n "${CERT_DIR}" ]]; then
   rm -f "${CERT_FILE}"
   rm -f "${KEY_FILE}"
fi

# exit with previously-stored exit code, after cleanup
exit $EXIT_CODE
