#!/bin/bash
#
# Copyright (c) 2019 Clementine Computing LLC.
# 
# This file is part of PopuFare.
# 
# PopuFare is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# PopuFare is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with PopuFare.  If not, see <https://www.gnu.org/licenses/>.
#

export BASEDIR="/home/bus"

. $BASEDIR/bin/common_values.sh

# Do this at startup, and again if we've gotten a dropfile flag telling us to do so...
#
generate_ssh_targets

supervisor_pidfile="/tmp/client_supervisor.pid"
supervisor_args="$BASEDIR/bin/ipc_server $BASEDIR/bin/billdb $BASEDIR/bin/piu_minder $BASEDIR/bin/diu_minder $BASEDIR/bin/passdb $BASEDIR/bin/avls $BASEDIR/bin/paddlemgr $BASEDIR/bin/gps_minder"

eqnum_file="$EQUIP_NUM_FILE"
checksum_path="$CHECKSUM_AND_VERSION_PATH"

function spawn_supervisor
{

  # If we have a client supervisor binary to run
  #
  if [ -f $BASEDIR/bin/client_supervisor ]; then

#    # If we also have a config file for the UI
#    #
#    if [ -f $BASEDIR/config/menu.xml ]; then
#      rm $supervisor_pidfile
#
#      # then run the whole shebang...
#      #
#      $BASEDIR/bin/client_supervisor $supervisor_args &
#      echo $! > $supervisor_pidfile
#      echo Spawned client_supervisor. PID = `cat $supervisor_pidfile`
#
#    # if we DON'T have one, we still need to download a config before we're viable...
#    #
#    else
#      rm -f config.tgz.*
#      $BASEDIR/bin/showmessage -b "Downloading Config..."
#    fi

    
      # If we've gotten here, the client_supervisor process should
      # be running or is stale, so cleanup and respawn
      #
      rm -f $supervisor_pidfile

      # then run the whole shebang...
      #
      $BASEDIR/bin/client_supervisor $supervisor_args &
      echo $! > $supervisor_pidfile
      echo Spawned client_supervisor. PID = `cat $supervisor_pidfile`

  # If we DON'T have one, we are either a new system or just badly broken so...
  #
  else

    # Go and remove all package records so we can start fresh...
    #
    rm -f  $BASEDIR/config/*.tgz.*
    $BASEDIR/bin/showmessage -b "Wait (~ 15 min)"

  fi
}

function check_update
{
  if [ ! -f $TUNNEL_DROPFILE ]; then return 1; fi;
  (  

    if [ -f "$eqnum_file" ]; then
      echo -en "`cat $eqnum_file`"; 
    else
      echo -en "0"
    fi

    for file in `ls $checksum_path/*.checksum`; do 
      echo -en "\t`echo $file | sed -r 's/^.*\/(.*)\.checksum$/\1/'`=`cat $file`"; 
    done; 
    echo;
  ) | nc -q1 localhost $UPDATE_DAEMON_PORT
}


while true; do

  echo "## heartbeat"

  #See if we need to spawn our client supervisor
  if [ ! -f $supervisor_pidfile ]; then
    spawn_supervisor;
    sleep $SLEEP_AFTER_SPAWN;
  else
    if [ ! -d /proc/`cat $supervisor_pidfile` ]; then
      spawn_supervisor;    
      sleep $SLEEP_AFTER_SPAWN;
    fi
  fi

  if [ -f $TUNNEL_DROPFILE ]; then echo "Checking for updates..."; fi

  check_update | 
    (
      while read client_file checksum file_size server_path file_version; do

        # If we've been asked to abort this update, do so before we start downloading if possible
        #
        if [ -f $UPDATE_ABORT_DROPFILE ]; then
          echo "Aborting update on request!";
          # generate new SSH target from dropfiles
          #
          generate_ssh_targets
          # clear the flag
          #
          rm -f $UPDATE_ABORT_DROPFILE
          # break out of the loop
          #
          break;
        fi

        # Generate dropfiles to tell the rest of the system what we're up to
        #
        echo "$file_size" > /tmp/$client_file.expected_size
        echo "$checksum" > /tmp/$client_file.expected_md5
        echo "$file_version" > /tmp/$client_file.expected_version

        echo "Downloading $client_file version $file_version to /tmp ($file_size bytes)"

        # Initiate a secure download to fetch this package down from the server
        #
        scp -i $SSH_IDENTITY $SCP_OPTIONS -P $SSH_PORT $SSH_TARGET:$server_path /tmp/$client_file

        # If we've already downloaded when we get the abort message
        #
        if [ -f $UPDATE_ABORT_DROPFILE ]; then
          echo "Aborting update on request!";

          # Clean up after ourselves
          #
          rm -f /tmp/$client_file.expected_size /tmp/$client_file.expected_md5
          rm -f  /tmp/$client_file.expected_version /install.sh /tmp/install.sh /tmp/$client_file

          # generate new SSH target from dropfiles
          #
          generate_ssh_targets

          # clear the flag
          #
          rm -f $UPDATE_ABORT_DROPFILE

          # break out of the loop
          #
          break;
        fi

        # If we indeed _got_ a file to begin with...  
        #
        if [ -f /tmp/$client_file ]; then

          # Start a subshell in which we...
          #
          (
            # set our pwd to /tmp/ where we downloaded our package
            #
            cd /tmp/;

            #    Execute our package installer script which will check the package checksum
            # and assuming that matches, it will extract the installer script embedded in the
            # package and execute it.
            #
            $BASEDIR/bin/apply_update.sh $client_file $checksum $file_size $server_path $file_version
          );
        fi

        # Clean up after ourselves (removing our during-update dropfiles)  
        #
        rm -f /tmp/$client_file.expected_size /tmp/$client_file.expected_md5

        # as well as the update file itself
        #
        rm -f  /tmp/$client_file.expected_version /install.sh /tmp/install.sh /tmp/$client_file

      done
    )

  echo "Sleeping..."  
  sleep $SLEEP_BETWEEN_UPDATES;
done

