#!/bin/bash
# Script to launch the ArcGIS Enterprise SDK installer

# Product Info
SimpleVersion=12.0
ProductVersion="${SimpleVersion}"
BaseVersion=` echo ${SimpleVersion} | sed 's/\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.[0-9][0-9]*$/\1\.\2/' `
PreviousVersions="11.5 11.4 11.3 11.2 11.1 11.0 10.9.1 10.9 10.8.1 10.8 10.7.1 10.7 10.6.1"
ProductName="ArcGIS Enterprise SDK $ProductVersion"
# PreviousProductName initialized later
product=EnterpriseSDK
shortname="enterprisesdk"
Esri_Hostname=` hostname -f `; export Esri_Hostname
platform=Linux

MINIMUM_NODE_VERSION=20.17.1
MAXIMUM_NODE_VERSION=22.13.1

# Installer configuration
locale -a | grep "^en_US.utf8$" >/dev/null 2>&1
if [ "$?" = "0" ]
then
    LANG=en_US.UTF-8; export LANG
    LC_CTYPE=en_US.UTF-8; export LC_CTYPE
    InstallerLang="-l en"
fi

# Setup functions
full_dirname() {
    Dirname=` dirname "$*" `
    if echo ${Dirname} | grep '^./' >/dev/null 2>&1
    then
        ScriptPath=`pwd``echo ${Dirname} | cut -d '.' -f2-`
    elif echo ${Dirname} | grep '^/' >/dev/null 2>&1
    then
        ScriptPath=${Dirname}
    elif [ "${Dirname}" = "." ]
    then
        ScriptPath=`pwd`
    else
        ScriptPath=`pwd`/${Dirname}
    fi

    echo ${ScriptPath}
}

error_header() {
    echo "[$ProductName Setup Error]" >&2
}

warning_header() {
    echo "[$ProductName Setup Warning]"
}

# Usage & Examples text
usage () {
    echo "Usage: Setup [OPTION]..."
    echo "  -m, --mode MODE            Optional. Defaults to GUI mode."
    echo "                             MODE is either silent or gui:"
    echo "                               silent:  Performs a silent install."
    echo "                                        See Silent Options section below."
    echo "                               gui:     X display is required."
    echo
    echo "  -v, --verbose              Installer runs in verbose mode."
    echo
    echo "  -h, --help                 Display this help and exit."
    echo
    echo "  -e, --examples             Display usage examples of these options and exit."
    echo
    echo
    echo "Silent Options - the following options are only used for silent mode installs:"
    echo "  -l, --license-agreement CHOICE"
    echo "                             Required for silent mode. CHOICE can be Yes or No."
    echo "                             Yes indicates that you have read and agreed to the"
    echo "                             Esri Master Agreement (E204CW). Please visit"
    echo "                             http://www.esri.com/legal/licensing-translations"
    echo "                             to read the agreement."
    echo
    echo "  -d, --directory DIRECTORY  Optional. By default,"
    echo "                             $ProductName will be installed to"
    echo "                             your \$HOME directory. DIRECTORY specifies a"
    echo "                             different installation directory."
    echo "                             Note: The path /arcgis/${shortname} will be"
    echo "                             appended to the installation directory."
    echo
    echo "  -c, --customdatafeedtool CHOICE"
    echo "                             Optional. CHOICE can be Yes or No. Default is Yes."
    echo "                             Yes installs the Custom Data Feed Tool feature,"
    echo "                             which provides the command line tool to create and"
    echo "                             manage custom data providers."
    echo "                             Custom Data Feed Tool requires Node.js version"
    echo "                             between ${MINIMUM_NODE_VERSION} and ${MAXIMUM_NODE_VERSION}."
    echo
}

usage_examples() {
    echo "$ProductName Setup script EXAMPLES:"
    echo
    echo "This will run the installer in GUI mode, allowing the user to make all"
    echo "selections at install time."
    echo "  Setup"
    echo 
    echo "These will run the installer in Silent mode, using the default installation"
    echo "directory \$HOME/arcgis/${shortname}/."
    echo "Note that these two commands perform the same actions."
    echo "  Setup -m silent -l yes"
    echo "  Setup --mode silent --license-agreement yes"
    echo 
    echo "This will run the installer in Silent mode, using the installation directory"
    echo "/opt/arcgis/${shortname}."
    echo "  Setup -m silent -l yes -d /opt/arcgis/${shortname}"
    echo 
}

create_prop_file() {
    # Create the temp file using mktemp
    Esri_Silent_Property_File=`mktemp`

    # Set the file to be removed on exiting the script
    trap 'rm -f $Esri_Silent_Property_File' EXIT

    # Check that file exists
    if [ ! -f $Esri_Silent_Property_File ]
    then
        error_header
        echo "Could not create temporary file for silent install." >&2
        echo "Please check that your user id has file creation permissions for the mktemp utility." >&2
        echo "Exiting." >&2
        exit 1;
    fi

    # Check that file is writeable
    if [ -w $Esri_Silent_Property_File ]
    then
        # Create our temp prop file to pass in to installer
cat << EOF >> $Esri_Silent_Property_File
# Esri $ProductName Silent Install Property File
USER_INSTALL_DIR=$Esri_Install_Directory
CHOSEN_INSTALL_FEATURE_LIST=$Chosen_Install_Feature_List
EOF
    else
        error_header
        echo "Could not write to temporary file $Esri_Silent_Property_File for silent install." >&2
        echo "Exiting." >&2
        exit 1;
    fi
}

append_to_install_dir() {
    # Strip any / from end of string
    Esri_Install_Directory=`echo $Esri_Install_Directory | sed "s;/$;;"`

    # Check if it ends with /arcgis
    echo $Esri_Install_Directory | grep -e "\/arcgis$" >/dev/null 2>&1

    # If so, append /${shortname}
    if [ "$?" = "0" ]
    then
        Esri_Install_Directory=${Esri_Install_Directory}/${shortname}
    fi

    # Check now if it ends with /arcgis/${shortname}
    echo $Esri_Install_Directory | grep -e "\/arcgis\/${shortname}$" >/dev/null 2>&1

    # If not, append /arcgis/${shortname}
    if [ "$?" != "0" ]
    then
        Esri_Install_Directory=${Esri_Install_Directory}/arcgis/${shortname}
    fi
}

check_valid_install_dir() {
    # Check for / at start of string
    echo $Esri_Install_Directory | grep -e "^\/" >/dev/null 2>&1

    if [ "$?" != "0" ]
    then
        error_header
        echo "Invalid argument to -d or --directory. The install directory" >&2
        echo "must be an absolute path. It should start with the / character." >&2
        echo "Exiting." >&2
        exit 1
    fi

    Check_Dir=$Esri_Install_Directory
    # Strip any / from end of string
    Check_Dir=`echo $Check_Dir | sed "s;/$;;"`

    # Check that this user can write to the directory
    if [ -d $Check_Dir ]
    then
        if [ ! -w $Check_Dir ]
        then
            error_header
            echo "This user does not have write permissions to the install directory provided." >&2
            echo "Please change the permissions or choose a different install directory." >&2
            echo >&2
            echo "User................`id -u -n`" >&2
            echo "Install Directory...$Check_Dir" >&2
            exit 1
        fi
    else
        # /${shortname} dir doesn't exist, check next level up
        Check_Dir=`echo $Check_Dir | sed "s;/${shortname}$;;"`
        if [ -d $Check_Dir ]
        then
            if [ ! -w $Check_Dir ]
            then
                error_header
                echo "This user does not have write permissions to the install directory provided." >&2
                echo "Please change the permissions or choose a different install directory." >&2
                echo >&2
                echo "User................`id -u -n`" >&2
                echo "Install Directory...$Check_Dir" >&2
                exit 1
            fi
        else
            # /arcgis dir doesn't exist, check next level up
            Check_Dir=`echo $Check_Dir | sed "s;/arcgis$;;"`
            if [ -d $Check_Dir ]
            then
                if [ ! -w $Check_Dir ]
                then
                    error_header
                    echo "This user does not have write permissions to the install directory provided." >&2
                    echo "Please change the permissions or choose a different install directory." >&2
                    echo >&2
                    echo "User................`id -u -n`" >&2
                    echo "Install Directory...$Check_Dir" >&2
                    exit 1
                fi
            else
                # Appended /arcgis & /${shortname} dir don't exist, and their parent doesn't exist. This directory must exist before the setup is run.
                error_header
                echo "Install directory [$Check_Dir] does not exist. Please create this directory first." >&2
                echo "Exiting." >&2
                exit 1
            fi
        fi
    fi
}

show_Node_js_warning() {
	echo "Node.js was not found on this system or is an unsupported version."
	echo "The Custom Data Feed Tool feature, used as a tool to create various data"
	echo "providers, will not be functional after installation."
	echo "If you need this feature, install Node.js version between ${MINIMUM_NODE_VERSION} and"
	echo "${MAXIMUM_NODE_VERSION} before running this setup program."
	echo
	echo "Installation will automatically continue in 10 seconds..."
	sleep 10
}

check_Node_js() {
    MINIMUM_NODE_MAJOR_VERSION=` echo $MINIMUM_NODE_VERSION | cut -f1 -d'.' `
    MIN_NUMBER_OF_ELEMENTS=` grep -o "\." <<< "$MINIMUM_NODE_VERSION" | wc -l `
    [[ $MIN_NUMBER_OF_ELEMENTS -ge 1 ]] && MINIMUM_NODE_MINOR_VERSION=` echo $MINIMUM_NODE_VERSION | cut -f2 -d'.' ` || MINIMUM_NODE_MINOR_VERSION=0
    [[ $MIN_NUMBER_OF_ELEMENTS -ge 2 ]] && MINIMUM_NODE_REVISION_VERSION=` echo $MINIMUM_NODE_VERSION | cut -f3 -d'.' ` || MINIMUM_NODE_REVISION_VERSION=0
    
    MAXIMUM_NODE_MAJOR_VERSION=` echo $MAXIMUM_NODE_VERSION | cut -f1 -d'.' `
    MAX_NUMBER_OF_ELEMENTS=` grep -o "\." <<< "$MAXIMUM_NODE_VERSION" | wc -l `
    [[ $MAX_NUMBER_OF_ELEMENTS -ge 1 ]] && MAXIMUM_NODE_MINOR_VERSION=` echo $MAXIMUM_NODE_VERSION | cut -f2 -d'.' ` || MAXIMUM_NODE_MINOR_VERSION=0
    [[ $MAX_NUMBER_OF_ELEMENTS -ge 2 ]] && MAXIMUM_NODE_REVISION_VERSION=` echo $MAXIMUM_NODE_VERSION | cut -f3 -d'.' ` || MAXIMUM_NODE_REVISION_VERSION=0

	# check for node
	which node >/dev/null 2>&1

	if [ $? -eq 0 ]
	then
		# check MINIMUM_NODE_VERSION <= node version <= MAXIMUM_NODE_VERSION
		NODE_VERSION=` node -v | tr -d 'v' ` # strip leading 'v' character from node output
		NODE_MAJOR_VERSION=` echo $NODE_VERSION | cut -f1 -d'.' `
		NODE_NUMBER_OF_ELEMENTS=` grep -o "\." <<< "$NODE_VERSION" | wc -l `
		[[ $NODE_NUMBER_OF_ELEMENTS -ge 1 ]] && NODE_MINOR_VERSION=` echo $NODE_VERSION | cut -f2 -d'.' ` || NODE_MINOR_VERSION=0
		[[ $NODE_NUMBER_OF_ELEMENTS -ge 2 ]] && NODE_REVISION_VERSION=` echo $NODE_VERSION | cut -f3 -d'.' ` || NODE_REVISION_VERSION=0

		if [[ ("${NODE_MAJOR_VERSION}" -lt "${MINIMUM_NODE_MAJOR_VERSION}") || ("${NODE_MAJOR_VERSION}" -eq "${MINIMUM_NODE_MAJOR_VERSION}" && "${NODE_MINOR_VERSION}" -lt "${MINIMUM_NODE_MINOR_VERSION}") || ("${NODE_MAJOR_VERSION}" -eq "${MINIMUM_NODE_MAJOR_VERSION}" && "${NODE_MINOR_VERSION}" -eq "${MINIMUM_NODE_MINOR_VERSION}" && "${NODE_REVISION_VERSION}" -lt "${MINIMUM_NODE_REVISION_VERSION}") ]]
		then
			show_Node_js_warning
		elif [[ ("${NODE_MAJOR_VERSION}" -gt "${MAXIMUM_NODE_MAJOR_VERSION}") || ("${NODE_MAJOR_VERSION}" -eq "${MAXIMUM_NODE_MAJOR_VERSION}" && "${NODE_MINOR_VERSION}" -gt "${MAXIMUM_NODE_MINOR_VERSION}") || ("${NODE_MAJOR_VERSION}" -eq "${MAXIMUM_NODE_MAJOR_VERSION}" && "${NODE_MINOR_VERSION}" -eq "${MAXIMUM_NODE_MINOR_VERSION}" && "${NODE_REVISION_VERSION}" -gt "${MAXIMUM_NODE_REVISION_VERSION}") ]]
		then
			show_Node_js_warning
		fi
	else
		show_Node_js_warning
	fi
}

# Parse command line arguments
# Set defaults
Esri_UI_Mode=gui
Esri_Install_Directory=$HOME/arcgis/${shortname}
Esri_Verbose=false
Esri_License_Agree=no
Chosen_Install_Feature_List="EntSDK,CDFTool"
CDFTool_selected="true"

# Get args
while [[ $1 = -* ]]; do
  case "$1" in
    -m|--mode)
      Esri_UI_Mode=`echo $2 | tr [A-Z] [a-z]`
      if [ -z "$2" ] || [[ $2 = -* ]] || [ "$Esri_UI_Mode" != "gui" -a "$Esri_UI_Mode" != "silent" ]
      then
        error_header
        echo "Empty or invalid argument to -m or --mode detected. See --help option for more details." >&2
        echo "Exiting." >&2
        exit 1
      else
        shift 2
      fi
      ;;
    -l|--license-agreement)
      Esri_License_Agree=`echo $2 | tr [A-Z] [a-z]`
      if [ -z "$2" ] || [[ $2 = -* ]] || [ "$Esri_License_Agree" != "yes" -a "$Esri_License_Agree" != "no" ]
      then
        error_header
        echo "Empty or invalid argument to -l or --license-agreement detected. See --help option for more details." >&2
        echo "Exiting." >&2
        exit 1
      else
        shift 2
      fi
      ;;
    -d|--directory)
      if [ -z "$2" ] || [[ $2 = -* ]]
      then
        error_header
        echo "Empty or invalid argument to -d or --directory detected. See --help option for more details." >&2
        echo "Exiting." >&2
        exit 1
      else
        Esri_Install_Directory="$2"
        append_to_install_dir
        check_valid_install_dir # This call should be after append_to_install_dir so we know that /arcgis/${shortname} is at end of string
        shift 2
      fi
      ;;
    -c|--customdatafeedtool)
      CDF_selected=`echo $2 | tr [A-Z] [a-z]`
      if [ -z "$2" ] || [[ $2 = -* ]] || [ "$CDF_selected" != "yes" -a "$CDF_selected" != "no" ]
      then
        error_header
        echo "Empty or invalid argument to -c or --customdatafeedtool detected. See --help option for more details." >&2
        echo "Exiting." >&2
        exit 1
      elif [ "$CDF_selected" = "yes" ]
      then
        Chosen_Install_Feature_List="EntSDK,CDFTool"
        CDFTool_selected="true"
        shift 2
      elif [ "$CDF_selected" = "no" ]
      then
        Chosen_Install_Feature_List="EntSDK"
        CDFTool_selected="false"
        shift 2
      fi
      ;;
    -v|--verbose)
      Esri_Verbose=true
      shift 1
      # Turns on InstallAnywhere debug statements
      LAX_DEBUG=true; export LAX_DEBUG
      ;;
    -h|--help)
      usage
      exit
      ;;
    -e|--examples)
      usage_examples
      exit
      ;;
    *)
      error_header
      echo "Error: Unknown option: $1" >&2
      exit 1
      ;;
  esac
done

# File Information
# Determine the path to the CD root directory.
ScriptPath=` full_dirname "$0" `
ScriptName=`basename "$0"`

if [ "$Esri_UI_Mode" = "silent" ]
then
	if [ "$Esri_License_Agree" = "yes" ]
	then
		if [ $CDFTool_selected = "true" ]
		then
			check_Node_js
		fi
	fi
fi

CurrentPropFile="$HOME/.ESRI.properties.` uname -n `.${SimpleVersion}"

# detect previous version(s)
PreviousVersion_Detected=false
for PreviousVersion in ${PreviousVersions}
do
    PreviousProductName="ArcGIS Enterprise SDK ${PreviousVersion}"
    PreviousVersion_Prop_File="$HOME/.ESRI.properties.` uname -n `.${PreviousVersion}"
    ProductInstallDir=""
    if [ -f ${PreviousVersion_Prop_File} ]
    then
        ProductInstallDir=` grep Z_${product}_INSTALL_DIR ${PreviousVersion_Prop_File} | cut -f2 -d= `
    fi

    DetectedSPLevel=""
    if [ "x${ProductInstallDir}" != "x" ] && [ -d ${ProductInstallDir} ]
    then
        PreviousVersion_Detected=true
        ProductPatchLog="${ProductInstallDir}/.ESRI_ESDK_PATCH_LOG"
        if [ -f ${ProductPatchLog} ]
        then
            DetectedSPLevel=` grep QFE_TITLE ${ProductPatchLog} | head -n1 | sed 's/^QFE_TITLE: //' `
        fi
        break
    fi
done

if [ ${PreviousVersion_Detected} = "true" ] # begin upgrade
then
    Esri_Install_Directory=${ProductInstallDir}
    if [ "x${DetectedSPLevel}" != "x" ]
    then
        if [ "` echo ${DetectedSPLevel} | grep "^[0-9]" `x" != "x" ]
        then
            DetectedPreviousProductName="${PreviousProductName} SP${DetectedSPLevel}"
        else
            DetectedPreviousProductName="${DetectedSPLevel}"
        fi
    else
        DetectedPreviousProductName=${PreviousProductName}
    fi

    echo "==================================================================="
    echo "${ProductName} (Linux)"
    echo "==================================================================="
    echo 
    echo "Your ${DetectedPreviousProductName} is installed at:"
    echo 
    echo " ${Esri_Install_Directory}"
    echo 
    echo "Confirm Settings"
    echo "==================================================================="
    echo "Product to upgrade:        ${DetectedPreviousProductName} (Linux)"
    echo "Location to upgrade:       ${Esri_Install_Directory}"
    echo 
    echo "Your ${DetectedPreviousProductName} will be stopped when performing the upgrade"
    echo "and ${ProductName} will be started after the upgrade completes."
    echo 
    if [ "$Esri_UI_Mode" = "silent" ]
    then
	echo "Upgrade will automatically continue in 10 seconds..."
        sleep 10
    else
        echo " 'y' to continue with these settings"
        echo " 'q' to exit without upgrading this product"
        echo ""
        echo "Enter choice [y,q] (y): "
        read upgrade_choice

        if [ "$upgrade_choice" = "q" ] || [ "$upgrade_choice" = "Q" ]
        then
            echo "Exiting script..."
            exit 1
        fi
    fi

    echo "Applying ${ProductName} to ${Esri_Install_Directory}."
    echo "Please wait..."

    # Back up config
    PreviousVersion_Backup_Dir=` mktemp -d `
    trap 'rm -rf $PreviousVersion_Backup_Dir' EXIT

    # backup user files

    # Remove previous Product
    if [ -f ${Esri_Install_Directory}/.Setup/qfe/removepatch.sh ]
    then
        Num_Patches=` ${Esri_Install_Directory}/.Setup/qfe/removepatch.sh -s | grep QFE_ID: | wc -l `
        if [ $Num_Patches -gt 0 ]
        then
            echo "Uninstalling patch(es)..."
            for i in {1..$Num_Patches}
            do
                ${Esri_Install_Directory}/.Setup/qfe/removepatch.sh -y >/dev/null 2>&1
            done
        fi
    fi
    echo "Uninstalling previous version..."
    sh ${Esri_Install_Directory}/uninstall_${product} -s >/dev/null 2>&1
    rm -f ${Esri_Install_Directory}/.Setup/build_number >/dev/null 2>&1

    # restore user files

    # Install current Product
    Esri_UI_Mode=silent
    Esri_License_Agree=yes
    echo "Installing upgrade..."
    PreviousVersion_UPGRADE=true; export PreviousVersion_UPGRADE
fi

if [ "$Esri_UI_Mode" = "silent" ]
then
    append_to_install_dir
    check_valid_install_dir # This call should be after append_to_install_dir so we know that /arcgis/${shortname} is at end of string

    if [ ${PreviousVersion_Detected} != "true" ]
    then
        echo "[$ProductName Installation Details]"
        echo "UI Mode..................$Esri_UI_Mode"
        echo "Agreed to Esri License...$Esri_License_Agree"
        echo "Installation Directory...$Esri_Install_Directory"
        echo "Chosen Features..........$Chosen_Install_Feature_List"
        echo
        echo "Starting installation of $ProductName..."
    fi
    sleep 2
else
    echo
    echo "Starting installation of $ProductName..."
fi

# Set env var for CD root directory
CD_ROOT="${ScriptPath}"; export CD_ROOT
InstallerLoc="${ScriptPath}/${product}/${platform}/Disk1/InstData/VM/install.bin"
if [ -f "$InstallerLoc" ]
then
{
    # Check if we are in GUI mode but no DISPLAY has been set. GUI mode is the default if no other choice is made.
    if [ "$Esri_UI_Mode" = "gui" ] && [ "x${DISPLAY}x" = "xx" ]
    then
        warning_header
        echo "This setup has detected that the DISPLAY variable has not been set, but silent mode was not selected."
        echo "Note: For information on the silent setup UI mode, please run this script with the --help option."
        echo
        echo "This setup will now exit."
        exit 1
    fi

    ESRI_EnterpriseSDK_PassedSetupChecks="true"; export ESRI_EnterpriseSDK_PassedSetupChecks

    # Launch the setup
    if [ "$Esri_UI_Mode" = "silent" ]
    then
        if [ "$Esri_License_Agree" = "yes" ]
        then
            create_prop_file
            sh "$InstallerLoc" -i silent -f "$Esri_Silent_Property_File" $InstallerLang
            Esri_IA_Exit_Code=$?
            if [ "$Esri_IA_Exit_Code" = "0" ]
            then
                echo "...$ProductName installation is complete."
            else
                error_header
                echo "...$ProductName installation is complete, but some errors or warnings occurred. [Exit Code: ${Esri_IA_Exit_Code}]" >&2
                echo "Please check this file for more information:" >&2
                echo "$Esri_Install_Directory/.Setup/${product}_InstallLog.log" >&2
                exit 1
            fi
        else
            error_header
            echo "Before the installer can run silently, you must read and agree to the Master Agreement." >&2
            echo "Please visit http://www.esri.com/legal/licensing-translations to read the agreement." >&2
            echo "Please see the --help option for further information." >&2
            echo >&2
            echo "Exiting." >&2
            exit 1;
        fi
    else
        echo
        echo "Note: For information on the silent setup UI mode, please run this script with the --help option."
        sleep 2
        echo
        sh "$InstallerLoc" -i gui $InstallerLang

        # reset Esri_Install_Directory in case user selected a non-default location in GUI
        Esri_Install_Directory=` grep Z_${product}_INSTALL_DIR ${CurrentPropFile} | cut -f2 -d= `
    fi
}
else
    error_header
    echo "Setup files missing. Please make sure the file ${InstallerLoc} is present and run the Setup script again." >&2
    echo "Exiting." >&2
    exit 1
fi

if [ ${PreviousVersion_Detected} = "true" ]
then
    cp -pRf ${PreviousVersion_Backup_Dir}/* ${Esri_Install_Directory}/ >/dev/null 2>&1
    rm -rf ${PreviousVersion_Backup_Dir} >/dev/null 2>&1
fi
