#!/usr/bin/env bash

set -e

function help() {
	cat <<EOF
usage: configure-vs-code [options] [vs-code-args]

Configure VS Code for use with Posit Workbench.

Examples
   configure-vs-code
   configure-vs-code --overwrite no
   configure-vs-code --overwrite yes --extensions-dir=/opt/code-server/extensions

Positional Arguments
   vs-code-args
         All additional arguments given to the script will be added to the args entry in 
         vscode.conf and passed to the VS Code binary when a session is started.

         --extensions-dir=<path>
               Specifies a global vscode extensions directory. If specified then
               this script will also install the Posit Workbench VS Code extension.

Options
   --overwrite <yes|no|prompt>
         What to do with existing configuration files. The default is "prompt".

            yes
                  overwrite existing files without prompting
            no
                  don't overwrite existing files, no prompt
            prompt
                  prompt for each existing file

   -h, --help
         Show this help.

EOF
}

overwrite=prompt

while [ ! -z "$1" ]; do
   case "$1" in
      --overwrite)
            overwrite="$2"
            shift
            ;;
      --help|-h)
            help
            exit 0
            ;;
      *)
         # pass all subsequent options through to vscode
         break
         ;;
   esac
   shift
done

case "$overwrite" in
    yes)
        ;;
    no)
        ;;
    prompt)
        ;;
    *)
        echo "Error: --overwrite=${overwrite} is not valid." >&2
        exit 1
        ;;
esac

# determine vscode config file
configDirs="$XDG_CONFIG_DIRS:/etc"
origIFS=IFS
IFS=':'; read -ra configDirList <<< "$configDirs"
for configDir in configDirList[@]
do
  if test -e "$configDir/rstudio/vscode.conf"
  then
    configFile="$configDir/rstudio/vscode.conf"
    break
  fi
done
IFS=$origIFS
if [[ $configFile == "" ]]
then
   configFile="/etc/rstudio/vscode.conf"
fi

# update vs code / RSP configuration
GENERATE_VSCODE_CONF=true
if [ -f $configFile ] 
then
   if [ $overwrite = "prompt" ]
   then
      cs_exe=$(grep exe $configFile | sed 's/.*\(exe=\)\(.[^ ]*\).*/\2/')
      if [ -z "$cs_exe" ]; then
         cs_exe="/usr/lib/rstudio-server/bin/code-server/bin/code-server"
      fi
      promptText1="The VSCode configuration file $configFile already exists"
      if [[ $cs_exe != */rstudio-server/bin/code-server* ]]; then
         promptText2=" and is configured to use an older version of VS Code - do you wish to regenerate it to use the latest supported version (y or n)? "
      else
         promptText2=" - do you wish to regenerate it (y or n)?"
      fi
      promptText="${promptText1}${promptText2}"
      while true; do
         read -p "${promptText} " yn
         case $yn in
            [Yy]* ) GENERATE_VSCODE_CONF=true; break;;
            [Nn]* ) GENERATE_VSCODE_CONF=false; break;;
            * ) echo "Invalid input - please input either yes or no";;
         esac
      done
   elif [ $overwrite = "no" ]
   then
      echo "${configFile} already exists, skipping"
      GENERATE_VSCODE_CONF=false
   fi
fi

if [ "$GENERATE_VSCODE_CONF" = true ]; then
   configContents="enabled=1
exe=/usr/lib/rstudio-server/bin/code-server/bin/code-server
args=--host=0.0.0.0 ${@}"

   echo "$configContents" > $configFile
   chmod 644 $configFile
   echo "$configFile generated"

   # Don't need to tell admin to restart server during installation; the installation itself
   # takes care of that. The postinst script invokes this script with "--overwrite no", so use
   # that as a hint that we're in the middle of an install vs. the script being run by an
   # administrator directly.
   if [ "$overwrite" != "no" ]; then
      DISPLAY_RESTART_HINT=true
   fi
else
   # update config to remove outdated code-server flag we set prior to Juliet Rose
   sed -iE "s|--disable-updates[ ]\?||" $configFile

   # code-server move the executable to /bin in 3.3.0
   # in case we are updating code-server, determine if the exe needs to be updated
   cs_exe=$(grep exe $configFile | sed 's/.*\(exe=\)\(.[^ ]*\).*/\2/')
   if [[ $cs_exe != */bin/* ]]
   then
      orig_cs_exe="$cs_exe"
      cs_exe=$(dirname $cs_exe)/bin/code-server
      sed -i "s|$orig_cs_exe|$cs_exe|" $configFile
   fi
fi

GENERATE_VSCODE_USER_SETTINGS=true
if [ -f "/etc/rstudio/vscode-user-settings.json" ]
then
   if [ $overwrite = "prompt" ]
   then
      while true; do
         read -p "The VSCode user settings json configuration file /etc/rstudio/vscode-user-settings.json already exists - do you wish to regenerate it (y or n)? " yn
         case $yn in
            [Yy]* ) GENERATE_VSCODE_USER_SETTINGS=true; break;;
            [Nn]* ) GENERATE_VSCODE_USER_SETTINGS=false; break;;
            * ) echo "Invalid input - please input either yes or no";;
         esac
      done
   elif [ $overwrite = "no" ]
   then
      echo "/etc/rstudio/vscode-user-settings.json already exists, skipping"
      GENERATE_VSCODE_USER_SETTINGS=false
   fi
fi

if [ "$GENERATE_VSCODE_USER_SETTINGS" = true ]; then
   userSettingsContents="{
      \"terminal.integrated.shell.linux\": \"$SHELL\",
      \"extensions.autoUpdate\": false,
      \"extensions.autoCheckUpdates\": false
}"
   
   echo "$userSettingsContents" > /etc/rstudio/vscode-user-settings.json
   chmod 644 /etc/rstudio/vscode-user-settings.json
   echo "/etc/rstudio/vscode-user-settings.json generated"
fi

if [[ "${@}" =~ "--extensions-dir" ]]
then
   rstudio-server install-vs-code-ext
fi

if [ "$DISPLAY_RESTART_HINT" = true ]; then
   echo "NOTE: New VS Code settings will not take effect until Posit Workbench is restarted (e.g. rstudio-server restart)."
fi
