#!/bin/bash

NEW_FPGA_FW=""
NEW_MICROCONTROLLER_FW=""
NEW_LINUX_KERNEL=""
RESTART="restart"

verify_running_on_nip() {
	if [[ "$HOSTNAME" == "nomad" ]]; then
		echo "Can only run this on the NIP."
		./bin/setled red
		exit 1
	fi
}

most_recent() {
	echo "$(ls -1vr $1 2>/dev/null | head -n1)"
}

install_bin() {
	local file=$1
	local install_dir=${2:-/usr/local/bin}
	local mode=${3:-0755}

	if [[ ! -e "${file}" ]] ; then
		echo "Unable to find $(basename ${file})"
		return
	fi

	mkdir -p ${install_dir}
	install -t ${install_dir} -m ${mode}  ${file}
	echo "installed $(basename ${file})"
}

install_bin_as() {
	local file=$1
	local dest=${2}
	local mode=${3:-0755}

	if [[ ! -e "${file}" ]] ; then
		echo "Unable to find $(basename ${file})"
		return
	fi

	if [[ -z "${dest}" ]] ; then
		echo "must specify destination name"
		return
	fi

	mkdir -p $(dirname ${dest})
	install  -m ${mode} -T ${file} ${dest}
	echo "installed $(basename ${dest})"
}

install_deb() {
	local file=$1

	if [[ ! -e "${file}" ]] ; then
		echo "unable to find $(basename ${file})"
		return
	fi

	dpkg -i ${file}
	echo "installed $(basename ${file})"
	echo
}



remove_old_programs() {
	echo "Removing old NIP programs"
	rm -f /usr/rppl/nipexec*
	rm -f {start,stop}-wifi
	rm -f {start,stop}-bluetooth

	echo "Removing nomad shared libraries"
	dpkg --purge nomad-libnipboard
	dpkg --purge nomad-libs
	rm -rf /usr/local/rppl/lib

	#remove udev rules
	echo "Removing NIP udev rules"
	rm -f /etc/udev/rules.d/98-nip-extvfat.rule

	#remove SysV init scripts if they are there
	echo "Removing NIP SysV scripts"
	rm -f /etc/init.d/rppl-nip
	rm -f /etc/rc2.d/S01rppl-nip

	#remove new services
	echo "Removing NIP services"
	systemctl disable /etc/systemd/system/rppl-nip.service
	rm -f /etc/systemd/system/rppl-nip.service
	rm -f /etc/systemd/system/rppl-update@.service
	systemctl daemon-reload

	echo "removing NIP Python libraries"
	/usr/bin/yes | pip3 uninstall Nomad-Utils  > /dev/null

	#pip3 uninstall wasn't removing stuff
	rm -rf /usr/local/bin/*
	rm -rf /usr/local/lib/python3.4/dist-packages/bench
	rm -rf /usr/local/lib/python3.4/dist-packages/[nN]omad*

	rm -f /usr/local/rppl/python/*


	echo "Removing NIP configuration files"
	rm -f /usr/rppl/nipc.conf
	rm -f /etc/nipc.conf
	echo "NIP programs removed"
	echo
}

install_new_programs() {
	echo "Installing NIP programs"

	# /etc config files
	if [[ -d  "./etc/nomad" ]] ; then
		echo "copying /etc confguration files"
		cp -dR ./etc/nomad/* /etc
		echo "... /etc configuration files installed."
	fi


	# /usr/local/bin
	install_bin "./bin/perf"

	install_bin "./urjtag/jtag"
	if [[ -d "./urjtag" ]] ; then
		mkdir -p /usr/local/share/urjtag
		cp -fR ./urjtag/* /usr/local/share/urjtag
		echo "installed jtag files"
	fi

	install_bin "./openocd/openocd"
	if [[ -d "./openocd" ]] ; then
		mkdir -p /usr/local/share/openocd
		cp -fR ./openocd/* /usr/local/share/openocd
		echo "installed openocd shared files"
	fi

	install_bin "./bin/nipspy"
	install_bin "./bin/nipserial"
	install_bin "./bin/cb_detect"
	install_bin "./bin/sys-detect"
	install_bin "./bin/niptest"

	#/usr/local/sbin
	install_bin "./bin/force-logrotate"  "/usr/local/sbin"
	install_bin_as "./bin/nomad-rppl-update" "/usr/local/sbin/rppl-update"
	install_bin_as "./bin/nomad-run-rppl-update" "/usr/local/sbin/run-rppl-update"
	echo

	#/usr/local/rppl
	if [[ -d "./deb" ]] ; then
		mkdir -p /usr/local/rppl
		cp -fd ./deb/linux*.deb /usr/local/rppl

		echo "coppied linux *.deb files"
		echo
	fi

	#/usr/local/rppl/python
	local PYDIR=/usr/local/rppl/python
	echo "Installing python packages"

	local pyutils=$(most_recent ./python/Nomad_Utils*.whl)
	if [[ ! -z "${pyutils}" ]] ; then
		mkdir -p ${PYDIR}
		cp -f ${pyutils} ${PYDIR}
		pip3 install ${PYDIR}/$(basename ${pyutils})

		echo "installed $(basename ${pyutils})"
	fi
	echo "installed python packages"
	echo


	#/usr/rppl
	install_bin "./bin/${NIPEXEC}" "/usr/rppl"
	( cd /usr/rppl && ln -fs ${NIPEXEC} nipexec )

	install_bin "./bin/${NIPEXEC}-debug" "/usr/rppl"

	if [[ -e "./nipexec_release_notes.md" ]] ; then
		echo "Installing release notes..."
		install_bin_as ./nipexec_release_notes.md /usr/rppl/nipexec_release_notes.md 0644
	fi	
	echo

	#/usr/local/rppl/lib
	install_deb ./deb/nomad-libs*.deb
	install_deb ./deb/nomad-libnipboard*.deb


	#nipc.conf
	_RIPPLE_SYSTEM=$(./bin/nomad-exec ./bin/sys-detect)
	if [[ -e $(which nomad-version) ]] ; then
		_tmp_sys=$(nomad-version -r)
		case ${_tmp_sys} in
		"244")
			if [[ "${_RIPPLE_SYSTEM}" != "NIP" ]] ; then
				echo "inconsistent RIPPLE_SYSTEM detected"
				echo "${_RIPPLE_SYSTEM} != ${_tmp_sys}"
				echo "using SYSTEM = NIP"
			fi
			_RIPPLE_SYSTEM="NIP"
			;;
		"1381")
			if [[ "${_RIPPLE_SYSTEM}" != "SCOUT" ]] ; then
				echo "inconsistent RIPPLE_SYSTEM detected"
				echo "${_RIPPLE_SYSTEM} != ${_tmp_sys}"
				echo "using SYSTEM = SCOUT"
			fi

			_RIPPLE_SYSTEM="SCOUT"
			;;
		*)
			echo "unable to detect system type [${_RIPPLE_SYSTEM}]"
			echo "using SYSTEM = NIP"
			_RIPPLE_SYSTEM="NIP"
			;;
		esac
	fi


	echo "SYSTEM = ${_RIPPLE_SYSTEM}" > /etc/nipc.conf
	echo "BTRIP = true" >> /etc/nipc.conf
	[[ "${OPT_TWONIP}" == "True" ]] && echo "TWONIP = true" >> /etc/nipc.conf
	[[ "${OPT_TCP}" == "True" ]]  && echo "TCP = true" >> /etc/nipc.conf
	echo "installed nipc.conf"
	echo "waiting for filesystem to sync"
	sync

	echo  "Installing NIP services"
	udevadm control --reload-rules
	udevadm trigger
	systemctl enable /etc/systemd/system/rppl-nip.service
	systemctl daemon-reload

	echo "NIP programs installed"
	echo
}


install_new_kernel() {
	local new_deb=$1

	echo "Installing new kernel : ${new_deb}"

	pushd . > /dev/null
	cd /usr/local/rppl
	DEBIAN_FRONTEND="noninteractive" dpkg --force-all -i ${new_deb}
	if (( $? != 0 )) ; then
		echo "Unable to install kernel: ${new_deb}"
		popd > /dev/null
		./bin/setled red
		exit 1
	fi
	popd > /dev/null

	RESTART="reboot"
}

check_kernel() {
	local cur new new_deb

	echo
	echo "Checking NIP kernel"
	new_deb=$(ls ./deb/linux-image* \
		  | sort -r -V  \
		  | head -n 1 \
		  | xargs basename )
	new=$(echo "${new_deb}" | sed 's/linux-image-\([^_]*\)_.*$/\1/g')
	cur=$(uname -r)
	to_install=$(echo -e "${new}\n${cur}" | sort -r -V | head -n 1)

	if [[ "${cur}" != "${to_install}" ]] ; then
		install_new_kernel ${new_deb}
	else
		echo "kernel ${cur} is most recent."
	fi

	NEW_LINUX_KERNEL="${new}"
}

install_fpga_firmware() {
	local ver=$1
	echo " Need to install fpga firmware ${ver}"

	cat <<-EOS | /usr/local/bin/jtag
		cable ft2232 vid=0403 pid=6010
		detect
		svf ./firmware/nipc.svf progress stop
EOS

	# this can eventually be restart as soon as we figure out how not to
	# keep running updates as soon as the isolated port powers up.
	RESTART="shutdown"
}

check_fpga_firmware() {
	local cur all new

	echo  "Checking on FPGA firmware"

	cur=$(lspci -d 0139: -vmm | grep "^Rev:" | awk '{print "r" $2; }')
	new="r04"

	if [[ "${cur}" != "${new}" ]]; then
		install_fpga_firmware ${new}
	elif [[ ! -z "${OPT_FORCE}" ]] ; then
		echo "FORCED install"
		install_fpga_firmware ${new}
	else
		echo "FPGA firmware ${cur} is most recent."
	fi

	NEW_FPGA_FW="${new}"
}

check_firmware() {
	echo
	echo "Verifying NIP firmware"
	check_fpga_firmware
	echo
}

delete_version_info() {
	rm -f /etc/rppl_version
}

write_version_info() {
	module_dir="/lib/modules/${NEW_LINUX_KERNEL}/kernel/drivers/rppl"
	cat <<-EOS > /etc/rppl_version
		kernel = ${NEW_LINUX_KERNEL}
		nipc_driver = $(modinfo -F version ${module_dir}/nipc.ko)
		nipc_firmware = "r04"
		nipexec = ${NIPEXEC}
		build_tag = ${BUILD_TAG}
		update = ${UPDATE_FILE}
	EOS
}


###############################################################################
#
#                            BEGIN SCRIPT HERE
#
###############################################################################

logfile=/var/log/nip-update.log
source ./build.info

LAST_UPDATE=$(grep -e '^update' /etc/rppl_version | sed 's/.*=\s*//g')
echo "LAST_UPDATE: ${LAST_UPDATE}"
echo "UPDATE_FILE: ${UPDATE_FILE}"

# set LED to White-Purple
./bin/setled white

#output to log file
exec &> >(tee -a "${logfile}")

echo
echo "[$(date)] Beggining rppl NIP update."
echo

delete_version_info
verify_running_on_nip
remove_old_programs
install_new_programs
check_kernel
check_firmware
write_version_info

#for now force a shutdown on any nipexec install
RESTART="shutdown"

echo
echo "[$(date)] update completed successfully"
echo

if [[ "${RESTART}" == "shutdown" ]] ; then
	touch /SHUTDOWN
elif [[ "${RESTART}" == "reboot" ]] ; then
	touch /REBOOT
fi

sync
exit 0

