#!/bin/bash
#
# This script copies the core Bela files to the board
# in preparation for building projects. It will remove any existing
# Bela directory before copying the files over

# Find location of this script so we can locate the rest of the files
SCRIPTDIR=$(dirname "$0")
[ -z "$SCRIPTDIR" ] && SCRIPTDIR="./" || SCRIPTDIR="$SCRIPTDIR"/ 
. "$SCRIPTDIR".bela_common || { echo "You must be in Bela/scripts to run these scripts" | exit 1; }  

[ -z "$IDE_FOLDER" ] && IDE_FOLDER=$SCRIPTDIR/../IDE
[ -z "$FORCE_REPLACE" ] && FORCE_REPLACE=0
FILES_TO_COPY="core include Makefile Makefile.libraries Makefile.linkbela examples Doxyfile scripts resources pru libraries"

# The following variables are manually copied from the Makefile.
# It is a bit nasty, but here we need to handle the case that the board may be 
# in any arbitrarily (bad) condition and try to handle it the best we can
BELA_IDE_SCREEN_NAME=IDE-Bela
SCREEN_NAME=Bela
REMOTE_UPDATE_LOG=$BBB_BELA_HOME/../update.log
LOCAL_UPDATE_LOG=`{ [ -z "$TMPDIR" ] && TMPDIR=/tmp; }; mktemp $TMPDIR/Bela-update.log.XXXXX || true`
DOLOG=1
FORCELOG=0

usage ()
{
    THIS_SCRIPT=`basename "$0"`
    echo "Usage: $THIS_SCRIPT [--clean] [--no-frills] [-dy ] [-i user@ip] [-b /path/to/remote/Bela]"

    echo "
    This script updates the core Bela files on the board, bringing it up
    to date with the files in the folder on the host computer.
    The script must be run once to initialize the board before running any of
    the other scripts in this directory. It must also be run every time you
    wish to update the core code.
    Running this script will discard all changes to the core code on the remote
    end.

Command line options:    
    -i arg : allows to set the username and IP address of the remote end (default: $BBB_ADDRESS)
    -b arg : allows to set the path to the Bela folder on the remote end. Use quotes if you use the \"~\" symbol (default: $BBB_BELA_HOME)
    --clean : removes all the files in the $BBB_BELA_HOME folder, INCLUDING any source code you may have in the $BBB_BELA_HOME/projects/ subdirectory.
    -d : skips re-generating Doxygen documentation on the board.
    -n : do not try to update the IDE.
    --no-frills : skips some optional commands.
    --log : force logging to $REMOTE_UPDATE_LOG on the board, using $LOCAL_UPDATE_LOG as a tmp file
    --no-log : avoids logging to file (see --log)
    --replace-user: replace user-editable scripts.
    -y : does not prompt the user before deleting the remote files.
    "
}

signal_handler ()
{
  echo
  exit
}

trap signal_handler 2 

error_handler () {
 [ $1 -eq 0 ] && printf "done\n" || { [ -z "$2" ] && printf "\nAn error occurred.\n" || printf "$2"; exit 1; }
}

FULL=1
OPTIND=1
ALWAYS_YES=0
RESET_BOARD=0
DOXYGEN=1
UPDATE_IDE=1
while [ "$1" != "" ]; do
  case $1 in
    -b)           
      shift
      BBB_BELA_HOME=$1
    ;;
    -i)
      shift
      BBB_ADDRESS=$1
    ;;
	--replace-user)
	  FORCE_REPLACE=1
	;;
    --clean)
      RESET_BOARD=1
	  FORCE_REPLACE=1
    ;;
    --log)
		FORCELOG=1
		DOLOG=1
	;;
    --no-log)
        DOLOG=0
    ;;
    -d)
      DOXYGEN=0
    ;;
    -n)
      UPDATE_IDE=0
    ;;
    --no-frills)
      FULL=0
    ;;
    -y)          
       ALWAYS_YES=1
    ;;
    *)            
      usage
      exit 1
    ;;
  esac
  shift
done

# make update is currently not calling --no-log, though it may in the future.
# For now, let's do heuristics to detect if we are being called by it (i.e.:
# the target is localhost) or this is an update procedure started from a remote
# machine.
if [ 0 -eq "$FORCELOG" ]; then
	if [ "$BBB_HOSTNAME" = 127.0.0.1 ]; then
		DOLOG=0
	fi
else
	DOLOG=1
fi

if [ 1 -eq "$DOLOG" ]; then
	# copy all following stdout/stderrr to UPDATE_LOG
	exec > >(tee "$LOCAL_UPDATE_LOG") 2>&1
	echo DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"`
	echo FILENAME=`basename $(cd $SCRIPTDIR/.. && pwd)`
	echo METHOD=update_board
fi

check_board_alive_and_set_date
# Check if destination folder exists
ssh "$BBB_ADDRESS" [ -d "$BBB_BELA_HOME" ] && DESTINATION_EMPTY=0 || DESTINATION_EMPTY=1

if [ "$DESTINATION_EMPTY" -eq 0 ];
then
  echo "Updating the Bela core code in $BBB_ADDRESS:$BBB_BELA_HOME"
  if [ "$RESET_BOARD" -eq 1 ];
  then
    printf "DANGER: you are about to perform a HARD RESET, which will DELETE all the existing files from the folder $BBB_BELA_HOME on the board.\nAre you sure you want to continue? (y/N) "
  else
    printf "All the changes to the CORE files in the remote folder $BBB_BELA_HOME will be LOST. The content of these files/folders will be lost:\n  $FILES_TO_COPY \nYour projects stored in $BBB_BELA_HOME/projects should be safe (and surely you have already backed them up somewhere safe, haven't you?).\nAre you sure you want to continue? (y/N) "
  fi;
  if [ "$ALWAYS_YES" -eq 1 ];
  then
    printf "y\n"
  else 
    read REPLY;
    [ -z "$REPLY" ] || { [ "$REPLY" !=  y ]  && [ "$REPLY" != Y ]; } && { echo "Aborting..."; exit 1; }
  fi
else
  echo "Installing Bela core code in $BBB_ADDRESS:$BBB_BELA_HOME"
  ssh "$BBB_ADDRESS" mkdir -p "$BBB_BELA_HOME"
fi

echo "Updating Bela core files to remote folder $BBB_BELA_HOME"
# Stop Bela if running and remove all files
if [ "$FULL" -eq 1 ]
then
  printf "Stopping Bela..." 
  ssh "$BBB_ADDRESS" "make -C \"$BBB_BELA_HOME\" idestop stop &>/dev/null; screen -X -S Bela quit &>/dev/null; screen -X -S IDE-Bela quit &>/dev/null; true";
  error_handler $?
fi

if [ "$RESET_BOARD" -eq 1 ];
then
  printf "Removing old files..."
  ssh "$BBB_ADDRESS" "rm -rf \"$BBB_BELA_HOME\"";
  error_handler $?
fi

#Check if rsync is available
check_rsync && RSYNC_AVAILABLE=1 || RSYNC_AVAILABLE=0

# cd to the home of the project to make the following lines less verbose
RUN_FOLDER=`pwd`
cd "$SCRIPTDIR"/../

printf "Updating files..."
# Copy relevant files to the board
if [ "$RSYNC_AVAILABLE" -eq 1 ];
then
  [ -z `which sed` ] && FILTER=cat || FILTER="sed s/\\n// | sed s/^.*:/Updated\ files:\/g | tr \"\n\" \" \""
  rsync -ac --no-t --exclude=.DS_Store,IDE/ide-dev.js --delete-after --stats $FILES_TO_COPY "$BBB_ADDRESS":"$BBB_BELA_HOME" 2>/dev/null |grep -i "Number" | grep -i "files" | grep -i "transferred" | eval "$FILTER" &&\
  printf "..."
else
  # if rsync is not available, then clean the folders before copying the files
  ssh "$BBB_ADDRESS" "cd '$BBB_BELA_HOME' && rm -rf $FILES_TO_COPY; mkdir -p \"$BBB_BELA_HOME\"" &&\
  scp -r -q $FILES_TO_COPY "$BBB_ADDRESS":"$BBB_BELA_HOME"
fi
error_handler $?

# build libraries required for Pd
ssh "$BBB_ADDRESS" "cd $BBB_BELA_HOME; for LIBRARY in Scope Midi Gui Trill Pipe; do make -f Makefile.libraries LIBRARY=\$LIBRARY; done"

# a bunch of files to be processed manually to special locations
ssh "$BBB_ADDRESS" "for DIR in \"$BBB_BELA_HOME\"/resources/tools/*; do [ -d \"\$DIR\" ] && { make -C \"\$DIR\" install || exit 1; }; done"
error_handler $?

# remove stale version of libs and incompatible programs from older versions
ssh "$BBB_ADDRESS" "rm -rf /usr/lib/libpd.so \"$BBB_BELA_HOME\"/lib/libpd.so \"$BBB_BELA_HOME\"/lib/libprussdrv.a \"$BBB_BELA_HOME\"/lib/libNE10.a \"$BBB_BELA_HOME\"/lib/libmathneon.a; dpkg -r supercollider-bela-xenomai-3 &> /dev/null"
error_handler $?

DEBIAN_VERSION=`get_board_debian_version`
# Install system-specific packages
ssh "$BBB_ADDRESS" "
	cd \"$BBB_BELA_HOME\"/resources/\"$DEBIAN_VERSION\"/deb/ &&\
	ls *.deb &>/dev/null &&\
	{
		dpkg -i *.deb && ldconfig || exit 1
	}; exit 0
	"
error_handler $?

if [ "$DEBIAN_VERSION" = wheezy ]
then
	# post-installation trigger for libseasocks
	ssh "$BBB_ADDRESS" "ln -f -s /usr/local/lib/libseasocks.so.1 /usr/local/lib/libseasocks.so && ldconfig /usr/local/lib" &&\
	# the below files could be user-customized, so copy them if they do not exist or forced to do so
	copy_if_does_not_exist resources/wheezy/sh/shutdown_switch.sh "" "$FORCE_REPLACE" &&\
	copy_if_does_not_exist resources/wheezy/sh/Bela_capeButtonHold.sh "" "$FORCE_REPLACE"
fi
error_handler $?

# Copy some custom files to the rootfs
if [ -d "resources/"$DEBIAN_VERSION"/rootfs/" ]
then
	scp -r resources/"$DEBIAN_VERSION"/rootfs/* "$BBB_ADDRESS":/
fi

# Create remaining directories needed for building
printf "Creating directory structure on the board..."
ssh "$BBB_ADDRESS" "mkdir -p \"$BBB_BELA_HOME\"/build/core \"$BBB_BELA_HOME\"/projects"
error_handler $?

if [ "$DOXYGEN" -eq 1 ] 
then 
  printf "Generating on-board documentation..."
  ssh "$BBB_ADDRESS" "cd \"$BBB_BELA_HOME\"; rm -rf Documentation/; doxygen &> /dev/null"
  error_handler $? "\nError while generating Doxygen documentation\n"
fi

if [ $FULL -eq 1 ]
then
  printf "Cleaning build environment..."
  ssh "$BBB_ADDRESS" "make -C \"$BBB_BELA_HOME\" --no-print-directory coreclean &>/dev/null"
  error_handler $? "\nError cleaning core\n"
fi

#-------------
#Installing IDE

if [ "$UPDATE_IDE" -eq 1 ]
then
	ls ./scripts/update_IDE >/dev/null 2>/dev/null
	if [ $? -eq 0 ]
	then
	  export BBB_ADDRESS BBB_BELA_HOME
	  ./scripts/update_IDE -y --no-frills
      [ "$FULL" -eq 1 ] && ssh "$BBB_ADDRESS" "make -C \"$BBB_BELA_HOME\" --no-print-directory idestart" 
	else
	  # run the IDE 
	   printf "\nThe Bela core files were updated on the board, but a valid IDE folder was not found in $IDE_FOLDER/, so the IDE was not updated
	You can get a copy of the most up-to-date IDE files from https://github.com/LBDonovan/bela-ide\n"
	  [ $FULL -eq 1 ] && printf "If there was an older version of the IDE on the board, it is being restarted.\n\n" &&\
	    ssh "$BBB_ADDRESS" "make -C \"$BBB_BELA_HOME\" --no-print-directory idestart &> /dev/null" 
	fi
else
	echo "Not updating the IDE"
fi
[ "$FULL" -eq 1 ] && ssh "$BBB_ADDRESS" make -C \"$BBB_BELA_HOME\" --no-print-directory idestartup nostartup && printf "The board will now run the IDE at startup, but startup of the Bela program has been disabled.\nTo enable it, use the set_startup.sh script.\nTo control the ide use the ide.sh script\n"

[ "$ALWAYS_YES" -eq 1 ] && printf "\nCore setup complete.\n\n" || {
  printf '\nSetup complete, press any key to continue . . .\n\n'
  read -n 1
}

# cd back to the original folder.
cd "$RUN_FOLDER"

if [ 1 -eq "$DOLOG" ]; then
	echo SUCCESS=true
	scp "$LOCAL_UPDATE_LOG" "$BBB_ADDRESS:$REMOTE_UPDATE_LOG"
	rm "$LOCAL_UPDATE_LOG"
fi
