#!/usr/bin/env bash

###################################################################################
# TRACE32 DVD installation script for linux based host systems and macOS.         #
# Copyright: (c) 1989-2017 Lauterbach GmbH, licensed for use with TRACE32(R) only #
###################################################################################

SCRIPTDIR=$( cd "$( dirname "$0" )" && pwd )
SCRIPTNAME=$( basename "$( readlink -fn "$0" )" )
INSTALLDIR=${1%/}
INSTALLUDEVROOT=$2
HOSTSYSTEM=""
UDEVINSTALL=0
ERRORCNT=0
OSSCRIPTNAME="$SCRIPTNAME"

if [ $( uname -s ) == "Darwin" ]; then 
	# In case this is a MacOSx installation
	HOSTSYSTEM="macosx64"
	INSTALLUDEVROOT=""
	OSSCRIPTNAME="setup_macos.sh"
fi

if [ "$INSTALLUDEVROOT" != "INSTALLUDEVROOTPART" ]; then
	# Check script directory
	if [ ! -d "$SCRIPTDIR/files/bin" ] || [ ! -f "$SCRIPTDIR/files/fcc.t32" ]; then
		echo "#T32: This script must be executed from the TRACE32 Release main directory."
		exit 1
	fi

	# Check given installation directory, otherwise use user's home directory
	if [ -z "$INSTALLDIR" ]; then
		echo "################################################################################"
		echo "#T32: This script installs TRACE32 to the subdirectory \"t32\" of your user's"
		echo "#     home directory. You can change the installation directory by passing the"
		echo "#     full path as first argument, e.g.: '$OSSCRIPTNAME \"/full/install/path\"'"
		echo "################################################################################"
		INSTALLDIR="~/t32"
	fi
	if [[ "$INSTALLDIR" == ~\/* ]]; then 
		USERHOME=$( echo ~ )
		INSTALLDIR=$( echo "$INSTALLDIR" | sed "s/^~\///g" )
		INSTALLDIR="$USERHOME/""$INSTALLDIR"
	fi
	echo

	while true; do
		read -p "#T32: TRACE32 installation directory will be \"$INSTALLDIR\"."$'\n      Proceed? (Yes/No) ' ans
		case $ans in
			[Yy]* ) break;;
			[Nn]* ) echo "#T32: Installation aborted by user."; exit;;
			* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
		esac
	done

	# Doublecheck if the directory exists and ask about replacements
	if [ -d "$INSTALLDIR" ]; then
		while true; do
			read -p "#T32: Installation directory already exists."$'\n      Do you want to overwrite it? (Yes/No) ' ans
			case $ans in
				[Yy]* ) echo "#T32: Proceeding..."; break;;
				[Nn]* ) echo "#T32: Installation aborted by user."; exit;;
				* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
			esac
		done
		# Check permissions for the installation directory
		if [ ! -w "$INSTALLDIR" ]; then
			echo "#T32: No write permission for \"$INSTALLDIR\"."
			echo "#T32: Installation aborted, run this script as root?"
			exit 1
		fi
	else
		# Check if directory creation succeeds
		mkdir -p "$INSTALLDIR"
		if [ $? -ne 0 ]; then
			echo "#T32: Error creating \"$INSTALLDIR\"."
			echo "#T32: Installation aborted, run this script as root?"
			exit 1
		fi
	fi

	# Try to determine host system in case of linux host
	if [ -z "$HOSTSYSTEM" ]; then
		if [ `getconf LONG_BIT` = "64" ]; then
			HOSTSYSTEM="pc_linux64"
		else
			HOSTSYSTEM="pc_linux"
		fi
	fi

	# Start installation
	mkdir -p "$INSTALLDIR/bin" "$INSTALLDIR/demo" "$INSTALLDIR/fonts" "$INSTALLDIR/pdf"
	cp -fv "$SCRIPTDIR"/files/* "$INSTALLDIR" 
	[[ $? -ne 0 && $? -ne 1 ]] && let ERRORCNT++
	cp -frv "$SCRIPTDIR"/files/bin/$HOSTSYSTEM "$INSTALLDIR/bin" || let ERRORCNT++
	cp -frv "$SCRIPTDIR"/files/demo/* "$INSTALLDIR/demo" || let ERRORCNT++
	cp -frv "$SCRIPTDIR"/files/fonts/* "$INSTALLDIR/fonts" || let ERRORCNT++
	cp -frv "$SCRIPTDIR"/files/pdf/* "$INSTALLDIR/pdf" || let ERRORCNT++
	chmod -R u+w "$INSTALLDIR"/* || let ERRORCNT++
	cp -fv "$INSTALLDIR"/demo/practice/t32.cmm "$INSTALLDIR/" || let ERRORCNT++
	mv -f "$INSTALLDIR"/bin/$HOSTSYSTEM/config.t32 "$INSTALLDIR/" || let ERRORCNT++
	chmod u+x "$INSTALLDIR"/bin/$HOSTSYSTEM/filecvt || let ERRORCNT++
	"$INSTALLDIR"/bin/$HOSTSYSTEM/filecvt "$INSTALLDIR" || let ERRORCNT++
	# Ensure permissions are correct
	chmod -R a+r "$INSTALLDIR" || let ERRORCNT++
	find "$INSTALLDIR"/bin -type f ! -name \*.* -name t32\* -exec chmod a+x {} \;  || let ERRORCNT++
	find "$INSTALLDIR" -type d -exec chmod a+x {} \;  || let ERRORCNT++
	if [ $ERRORCNT -eq 0 ]; then
		echo "#T32: Successfully finished file transfer and convert."
	else
		echo
		echo "#T32 ERROR: File transfer/convert finished with $ERRORCNT errors."
		echo "#           Please check your disc space and reinstall TRACE32"
		echo "#           or contact the technical support."
	fi
	echo
	
	# Check udev method for USB-Devices (just for linux hosts)
	if [ $HOSTSYSTEM != "macosx64" ]; then 
		while true; do
			read -p "#T32: Do you want to install proper udev rules for debuggers attached via USB?"$'\n      (Yes/No) ' ans
			case $ans in
				[Yy]* ) echo "#T32: Checking permissions to proceed..."; UDEVINSTALL=1; break;;
				[Nn]* ) echo "#T32: No udev rules will be installed, proceeding..."; break;;
				* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
			esac
		done
	fi
else
	HOSTSYSTEM="$3"
	UDEVINSTALL=1
fi

if [ $UDEVINSTALL -gt 0 ]; then
	# Check permissions for the udev rules directory
	if [ ! -w "/etc/udev/rules.d" ]; then
		echo "#T32: No write permission for \"/etc/udev/rules.d\"."
		if [ "$INSTALLUDEVROOT" != "INSTALLUDEVROOTPART" ]; then
			if [ "$EUID" -ne 0 ]; then
				#Call this part of the script as root to install udev rules
				if [ -z $(which sudo 2>/dev/null) ]; then
					#if sudo is not available use the su fallback method
					TRIES=0
					while true; do
						let TRIES++
						read -p "#T32: Do you want to run this installation part as root?"$'\n      (Yes/No) ' ans
						case $ans in
							[Yy]* ) su -m -c "'$SCRIPTDIR'/'$SCRIPTNAME' '$INSTALLDIR' 'INSTALLUDEVROOTPART' '$HOSTSYSTEM'" 
									if [[ $? -eq 0 || TRIES -gt 2 ]]; then break
									else echo "Sorry, try again";
									fi;;
							[Nn]* ) echo "#T32: Installation of udev rules aborted by user (no root access)."$'\n      Please install udev rules manually to access Lauterbach USB-Devices.'; break;;
							* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
						esac
					done
					if [ $TRIES -gt 3 ]; then
						echo "#T32: Could not get root access, cancelling installation of udev rules."
						echo "      Please install udev rules manually to access Lauterbach USB-Devices."
					fi
				else
					while true; do
						read -p "#T32: Do you want to run this installation part as root?"$'\n      (Yes/No) ' ans
						case $ans in
							[Yy]* ) sudo su -m -c "'$SCRIPTDIR'/'$SCRIPTNAME' '$INSTALLDIR' 'INSTALLUDEVROOTPART' '$HOSTSYSTEM'"; break;;
							[Nn]* ) echo "#T32: Installation of udev rules aborted by user (no root access)."$'\n      Please install udev rules manually to access Lauterbach USB-Devices.'; break;;
							* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
						esac
					done
				fi
			else
				echo "#T32: Cancelling installation of udev rules (missing permissions)."
				echo "      Please install udev rules manually to access Lauterbach USB-Devices."
			fi
		else
			echo "#T32: Cancelling installation of udev rules now."
			echo "      Please install udev rules manually to access Lauterbach USB-Devices."
		fi
		echo "#T32: Proceeding..."
	else
		FILECOPY=0
		if [ -f "/etc/udev/rules.d/10-lauterbach.rules" ]; then
			while true; do
				read -p "#T32: The Lauterbach udev rule file already exists."$'\n      Do you want to overwrite and update it? (Yes/No) ' ans
				case $ans in
					[Yy]* ) echo "#T32: Updating Lauterbach udev rules now."; FILECOPY=1; break;;
					[Nn]* ) echo "#T32: Update of Lauterbach udev rules aborted by user."; break;;
					* ) echo "#T32: Please answer \"Yes\" or \"No\".";;
				esac
			done
		else
			FILECOPY=1
		fi

		if [ $FILECOPY -gt 0 ]; then
			# Get kernel number
			KERNVER=$( uname -r | awk -F . '{print $1}' )
			KERNMAJ=$( uname -r | awk -F . '{print $2}' )
			KERNMIN=$( uname -r | awk -F . '{print $3}' )
			UDEVVER=$( udevadm --version )

			if [ "$KERNVER" -le 2 ]&&[ "$KERNMAJ" -le 6 ]&&[ "$KERNMIN" -le 31 ]; then
				if [ "$UDEVVER" -le 97 ]; then
					cp -fv "$SCRIPTDIR""/files/bin/$HOSTSYSTEM/udev.conf/kernel_upto_2.6.31/udev_upto_097/10-lauterbach.rules" "/etc/udev/rules.d"
				else
					cp -fv "$SCRIPTDIR""/files/bin/$HOSTSYSTEM/udev.conf/kernel_upto_2.6.31/udev_starting_098/10-lauterbach.rules" "/etc/udev/rules.d"
				fi
			else
				cp -fv "$SCRIPTDIR""/files/bin/$HOSTSYSTEM/udev.conf/kernel_starting_2.6.32/10-lauterbach.rules" "/etc/udev/rules.d"
			fi
		fi
	fi
fi


if [ "$INSTALLUDEVROOT" != "INSTALLUDEVROOTPART" ]; then
	# Create temporary directory and some example configurations
	mkdir -p "$INSTALLDIR"/tmp || let ERRORCNT++
	chmod a+rwx "$INSTALLDIR"/tmp || let ERRORCNT++
	 
	echo "#T32: Creating config files..."

	HOSTMCICONFIG=";Example configuration file generated by the $OSSCRIPTNAME installer script.
;Also see the example config.t32 in your installation directory.
;================================================================

;Environment Variables
OS=
SYS=$INSTALLDIR
TMP=$INSTALLDIR/tmp

;Connection to Host
PBI=MCILIB

;SCREEN settings
SCREEN=
HEADER=TRACE32 HostMCI configuration"

	echo "$HOSTMCICONFIG" > "$INSTALLDIR"/config_hostmci.t32 || let ERRORCNT++
	echo "$HOSTMCICONFIG" | sed "s/^PBI=.*/PBI=SIM/g" | sed "s/^HEADER=.*/HEADER=TRACE32 Simulator configuration/g" > "$INSTALLDIR"/config_sim.t32 || let ERRORCNT++
	echo "$HOSTMCICONFIG" | sed $'s/^PBI=.*/PBI=\\\nUSB/g' | sed "s/^HEADER=.*/HEADER=TRACE32 USB-Debugger configuration/g" > "$INSTALLDIR"/config_usb.t32 || let ERRORCNT++
	echo "$HOSTMCICONFIG" | sed $'s/^PBI=.*/PBI=\\\nNET\\\nNODE=<IP_or_Nodename>/g' | sed "s/^HEADER=.*/HEADER=TRACE32 Ethernet-Debugger configuration/g" > "$INSTALLDIR"/config_eth.t32 || let ERRORCNT++
	echo
	echo "################################################################################"
	echo "#T32: Installation of TRACE32 finished."
	if [ $ERRORCNT -ne 0 ]; then
		echo "#ERRORS during installation: $ERRORCNT"
		echo "#       Please check previous output and / or contact the technical support."
	fi
	echo "#"
	echo "#     To start TRACE32 you will find 4 example configuration files in the"
	echo "#     installation directory:"
	echo "#     - config.t32          explaining general config-file syntax."
	echo "#     - config_usb.t32      example to start USB-Debugger configurations"
	echo "#     - config_eth.t32      example to start Ethernet-Debugger configurations"
	echo "#                           (adapt the debugger IP-address inside!)"
	echo "#     - config_hostmci.t32  example to start HostMCI configurations"
	echo "#     - config_sim.t32      example to start Simulator configurations"
	echo "################################################################################"
	echo
	echo "Example 1: Start TRACE32 with an attached USB-Debugger for ARM 64bit targets:"
	echo " \"$INSTALLDIR/bin/$HOSTSYSTEM/t32marm64-qt\" -c \"$INSTALLDIR/config_usb.t32\""
	echo "Example 2: Start TRACE32 as PowerPC simulator:"
	echo " \"$INSTALLDIR/bin/$HOSTSYSTEM/t32mppc-qt\" -c \"$INSTALLDIR/config_sim.t32\""
	echo
fi

if [ $ERRORCNT -ne 0 ]; then
	exit 1
fi
