#!/bin/bash

UPDATE_COMMAND_MAX_VERSION="3.3.1"

GET_CURRENT_VERSION_VERSION="1"

#
# This script needs to be backwards compatible down to version 3.0.0
# And upward compatible to version listed above.
#

# Usage 
#
## ALL VERSIONS MUST SUPPORT THIS
# > Update.command
# Ask to updates SS3 in the current directory with the latest production version
# If no ask, to update a specific version.
#
# > Update.command --force
# Updates SS3 in the current directory with the latest production version
# Reinstall if the same or eariler that the current.
#
# > Update.command --patch
# Patch SS3 with the available patches.
#
## ALL VERSIONS MUST SUPPORT THIS
# > Update.command --version
# returns the version of tied with the Update.command files.
# 
## ALL VERSIONS MUST SUPPORT THIS
# > Update.command --backup
# Backups up the files.
# 
# > Update.command --install [ latest | { version } ]
# Updates to the version specified.
# 
# > Update.command --install [ latest | { version } ] --force
# Updates to the version specified.
# Reinstall if the same or eariler that the current.
# 
## ALL VERSIONS MUST SUPPORT THIS
# > Update.command --source { directory } --destination { directory }
# Updates SS3 in the destination using SS3 in the source directory. 


#Constants
DATE=`date +%Y%m%d%H%M%S`

PRODUCTION_VERSION_FN='SignStream3-version.txt'
PRODUCTION_VERSION_URL='http://dai.cs.rutgers.edu/SignStream/download/release/'"$PRODUCTION_VERSION_FN"

NEW_VERSION_URL=$PRODUCTION_VERSION_URL

SIGNBANK_UPDATE_COMMAND='GetSignBank.command'
DISABLE_QUARANTINE_COMMAND='DisableQuarantine.command'

SIGNBANK_LICENSE_FN='LICENSE-SignBank.txt'
SIGNBANK_LICENSE_URL='http://dai.cs.rutgers.edu/SignBank/'"$SIGNBANK_LICENSE_FN"

SIGNBANK_FN='globalSignBank.xml'

STOPPED_FILE='stopped_ss3'

SIGNSTREAM_PROCESS_NAME='SignStream3'

ORIG_DIR=$( pwd )

ORIG_CMD="$0"
ORIG_ARGS+=("$1")
ORIG_ARGS+=("$2")
ORIG_ARGS+=("$3")
ORIG_ARGS+=("$4")
ORIG_ARGS+=("$5")
ORIG_ARGS+=("$6")

#Temp Directory to hold new files.
TMP_DIR='/tmp/temp_SIGNSTREAM-'"$DATE"

# Navigate to root SignStream directory

CMD="$( basename "$0" )"
PROCID="$$"

DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "${DIR}"

INFO_FILE='SignStream3.app/Contents/Resources/info.txt'

CURRENT_INFO_FILE="$DIR"'/'"$INFO_FILE"

PLIST_FILE='SignStream3.app/Contents/Info.plist'

CURRENT_PLIST_FILE="$DIR"'/'"$PLIST_FILE"


BACKUP_DIR="signstream3-backup"

BACKUP_DIR_DATE="$BACKUP_DIR"'-'"$DATE"
BACKUP_FN_DATE='SignStream3-Backup-'"$DATE"'.tar.gz'

TERMINAL_NAME="$CMD""$PROCID"

set_terminal_name(){
  echo -n -e "\033]0;""$1""\007" # changes the running Terminal name for use when closing below
}


usage () {
  echo "Usage: $0 [ --force | ]"
  echo "Usage: $0 --version"
  echo "Usage: $0 --install [ latest | {version} ] [ --force | ]"
  echo "Usage: $0 --patch"
  echo "Usage: $0 --patch --install [ latest | {version} ] [ --force | ]"
  echo "Usage: $0 --backup"
  echo "Usage: $0 --source {dir} --destination {dir}"
}



close (){
  echo ""
  echo "You can now close this window (click 'X', or press enter, to close)."
  if [ -e "$ORIG_DIR" ]; then
    cd "$ORIG_DIR"
  fi
  read junk
  $( while pgrep -f "$CMD" | grep '^'"$PROCID"'$' &>/dev/null; do sleep 1; done; osascript -e 'tell application "Terminal" to close (first window whose name contains "'"$TERMINAL_NAME"'")' &> /dev/null ) &
  exit
}



ACTION="ALL"
FORCE_PATCH="false"
FORCE_NEW_VERSION="false"

if [[ "x""$1" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED=""
  cd "${DIR}"
elif [[ "x""$1" == "x--force" ]] && [[ "x""$2" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED=""
  FORCE_NEW_VERSION="true"
  cd "${DIR}"
elif [[ "x""$1" == "x--install" ]] && [[ "x""$2" != "x" ]] && [[ "x""$3" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED="$2"
  cd "${DIR}"
elif [[ "x""$1" == "x--install" ]] && [[ "x""$2" != "x" ]] && [[ "x""$3" == "x--force" ]] && [[ "x""$4" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED="$2"
  FORCE_NEW_VERSION="true"
  cd "${DIR}"
elif [[ "x""$1" == "x--patch" ]] && [[ "x""$2" == "x" ]]; then
  ACTION="PATCH"
  FORCE_PATCH="true"
  cd "${DIR}"
elif [[ "x""$1" == "x--patch" ]] && [[ "x""$2" == "x--install" ]] && [[ "x""$3" != "x" ]] && [[ "x""$4" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED="$3"
  FORCE_PATCH="true"
  cd "${DIR}"
elif [[ "x""$1" == "x--patch" ]] && [[ "x""$2" == "x--install" ]] && [[ "x""$3" != "x" ]] && [[ "x""$4" == "x--force" ]] && [[ "x""$5" == "x" ]]; then
  set_terminal_name "$TERMINAL_NAME"
  ACTION="ALL"
  NEW_VERSION_REQUESTED="$3"
  FORCE_PATCH="true"
  FORCE_NEW_VERSION="true"
  cd "${DIR}"
elif [[ "x""$1" == "x--version" ]] && [[ "x""$2" == "x" ]]; then
  ACTION="VERSION"
  cd "${DIR}"
elif [[ "x""$1" == "x--backup" ]] && [[ "x""$2" == "x" ]]; then
  ACTION="BACKUP"
elif [[ "x""$1" == "x--source" ]] && [[ "x""$2" != "x" ]] && [[ "x""$3" == "x--destination" ]] && [[ "x""$4" != "x" ]] && [[ "x""$5" == "x" ]]; then
  cd "${DIR}"
  ACTION="UPDATE"
# Make these absolute paths if not beginning with / 
  if [[ "$4" == /* ]]; then
    DEST_DIR="$4"
  else
    DEST_DIR="$ORIG_DIR"/"$4"
  fi
  if [[ "$2" == /* ]]; then
    SRC_DIR="$2"
  else
    SRC_DIR="$ORIG_DIR"/"$2"
  fi
  cd "${DIR}"
else
  set_terminal_name "$TERMINAL_NAME"
  echo "Error in usage: $@"
  echo ""
  usage
  close 
fi


# $1 > $2 : return 1
# $1 = $2 : return 0
# $1 < $2 : return 2
vercomp () {
    if [[ "x""$1" == "x""$2" ]]
    then
        return 0
    fi
    local IFS=.
    local i ver1=($1) ver2=($2)
    # fill empty fields in ver1 with zeros
    for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
    do
        ver1[i]=0
    done
    for ((i=0; i<${#ver1[@]}; i++))
    do
        if [[ -z ${ver2[i]} ]]
        then
            # fill empty fields in ver2 with zeros
            ver2[i]=0
        fi
        if ((10#${ver1[i]} > 10#${ver2[i]}))
        then
            return 1
        fi
        if ((10#${ver1[i]} < 10#${ver2[i]}))
        then
            return 2
        fi
    done
    return 0
}



# verbetween 1 0 3: return 4
# verbetween 1 1 3: return 2
# verbetween 1 2 3: return 0
# verbetween 1 3 3: return 1 
# verbetween 1 4 3: return 3
verbetween() {
  vercomp "$1" "$3"
  if [[ "$?" -eq 1 ]]; then
    min="$3"
    max="$1"
  else
    min="$1"
    max="$3"
  fi
 vercomp "$min" "$2"
  if [[ "$?" -eq 1 ]]; then
    return 4
  elif [[ "$?" -eq 0 ]]; then
    return 2 
  elif [[ "$?" -eq 2 ]]; then
    vercomp "$2" "$max"
    if [[ "$?" -eq 2 ]]; then
      return 0
    elif [[ "$?" -eq 0 ]]; then
      return 1
    else
      return 3
    fi
  fi
}


# This is specific to $GET_CURRENT_VERSION
get_current_version() {

if [[ "x""$GET_CURRENT_VERSION_VERSION" == "x1" ]]; then
  CURRENT_VERSION=$( cat "$CURRENT_PLIST_FILE" | grep -A 1 '<key>CFBundleVersion</key>' | grep '.*<string>.*</string>.*' | sed -e 's/.*<string>\(.*\)<\/string>.*/\1/' )
elif [[ "x""$GET_CURRENT_VERSION_VERSION" == "x2" ]]; then
  CURRENT_VERSION=$( sed -n 's/app_version \(.*\)$/\1/p' "$CURRENT_INFO_FILE" )
else
  CURRENT_VERSION="0.0.0"
fi

}


get_new_version () {

#If no explict version is request, get the latest
#Might change this to ask for a version
if [[ "x""$NEW_VERSION_REQUESTED" == "x" ]]; then
  echo ""
  echo "No explicit version of SignStream3 requested." 
  echo "Do you wish to install the latest available version? (Please answer \"yes\" or \"no\")"

  while true; do
    read -p "" yn
    if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
      echo "You answered \"yes\". The latest SignStream3 will be installed."; 
      break;
    elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
      echo  "You answered \"no\"."; 
      break;
    else
      echo "Please answer \"yes\" or \"no\".";
    fi
  done

  if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
    NEW_VERSION_REQUESTED="latest"
  else
    echo ""
    echo "SignStream3 versions are in the format d.d.d"
    echo "Do you wish to install another specific version of SignStream3?"
    echo "If so please enter the version number you want to install,"
    echo "or enter \"no\" to quit."

    while true; do
      read -p "" vn
      if [[ "$vn" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 
        echo "You answered version number \"$vn\"."; 
        break;
      elif [[ "$vn" =~ ^(N|n|NO|No|no)$ ]]; then
        echo "You answered \"no\". SignStream 3 will not be updated"; 
        break;
      else
        echo "Please answer the SignStream3 version number or \"no\".";
      fi
    done

    if [[ "$vn" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
      NEW_VERSION_REQUESTED="$vn"
    else
      echo ""
      echo "If you want to update the SignBank, please run the command $SIGNBANK_UPDATE_COMMAND."
      close
    fi
  fi
fi


if [[ "x""$NEW_VERSION_REQUESTED" == "xlatest" ]]; then
  echo ""
  echo "Attempting to update to the latest version."
  NEW_VERSION_FN='SignStream3-version.txt'
  NEW_VERSION_URL='http://dai.cs.rutgers.edu/SignStream/download/release/'"$NEW_VERSION_FN"

  # Get the Latest Production version of SignStream3
  NEW_VERSION_REQUEST=$( curl -L --silent --write-out "\nHTTPSTATUS:%{http_code}" "$NEW_VERSION_URL" )
  if [ "x"$( echo "$NEW_VERSION_REQUEST" | grep '^HTTPSTATUS:' | sed -e 's/HTTPSTATUS://' ) != "x200" ]; then
    echo "An error occurred while identifying the latest version of SignStream3."
    echo "Please check your internet connection."
    close
  fi
  NEW_VERSION=$( echo "$NEW_VERSION_REQUEST" | head -1 )
  echo "The latest version is currently $NEW_VERSION."
else
  echo "Attempting to update to the version of $NEW_VERSION_REQUESTED."
  NEW_VERSION=$NEW_VERSION_REQUESTED
fi

}


verify_new_version_exists () {

#Change signstream url based on version tag provided in version file
NEW_SIGNSTREAM_FN='SignStream3-'"$NEW_VERSION"'.zip'
NEW_SIGNSTREAM_URL='http://dai.cs.rutgers.edu/SignStream/download/release/'"$NEW_SIGNSTREAM_FN"


#Download the new version of SignStream version from DAI.
echo ""
echo "Verifying the $NEW_VERSION Version of SignStream3 exists..."

if ! curl -L --range 0-0 --silent --fail --output /dev/null "$NEW_SIGNSTREAM_URL"; then
  echo "The new version $NEW_VERSION does not appear to exist."
  echo "Please verify it does exist and is downloadable from here"
  echo "$NEW_SIGNSTREAM_URL"
  close
fi

echo "It Exists."

}




confirm_update () {

echo ""
echo "Current SignStream3 Version: $CURRENT_VERSION"
echo "New SignStream3 Version: $NEW_VERSION"
echo ""

# Only ask if not forced
if [[ "x""$FORCE_NEW_VERSION" != "xtrue" ]]; then

  vercomp "$NEW_VERSION" "$CURRENT_VERSION"
  if [[ "$?" -eq 0 ]]; then

    echo "The current and new versions of SignStream3 are the same."
    echo "No Update available for SignStream3."
    echo ""
    echo "Do you wish to reinstall this version? (Please answer \"yes\" or \"no\")"

    while true; do
      read -p "" yn
      if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
        echo "You answered \"yes\". SignStream3 will be reinstalled."; 
        break;
      elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
        echo "You answered \"no\".";
        break;
      else
        echo "Please answer \"yes\" or \"no\".";
      fi
    done

    if [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
      echo ""
      echo "If you want to update the SignBank, please run the command $SIGNBANK_UPDATE_COMMAND."
      close
    fi
  fi

  vercomp "$NEW_VERSION" "$CURRENT_VERSION"
  if [[ "$?" -eq 2 ]]; then
    echo "The new version of SignStream3 is older than your current version."
    echo "No Update available for SignStream3."
    echo "Do you wish to downgrade this version? (Please answer \"yes\" or \"no\")"

    while true; do
      read -p "" yn
      if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
        echo "You answered \"yes\". SignStream3 will be downgraded."; 
        break;
      elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
        echo "You answered \"no\"."; 
        break;
      else 
        echo "Please answer \"yes\" or \"no\".";
      fi
    done

    if [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
      echo ""
      echo "If you want to update the SignBank, please run the command $SIGNBANK_UPDATE_COMMAND."
      close
    fi
  fi

  vercomp "$NEW_VERSION" "$CURRENT_VERSION"
  if [[ "$?" -eq 1 ]]; then
    echo "Do you still wish to get the new version noted above?"
    echo "(Please answer \"yes\" or \"no\")"

    while true; do
      read -p "" yn
      if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
        echo "You answered \"yes\". SignStream3 will be updated.";
        break;
      elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
        echo "You answered \"no\"."; 
        break;
      else 
        echo "Please answer \"yes\" or \"no\".";
      fi
    done

    if [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
      echo ""
      echo "If you want to update the SignBank, please run the command $SIGNBANK_UPDATE_COMMAND."
      echo "If you want to install another version of SignStream3, contact the System Administrator." 
      close
    fi
  fi
fi

}


# cd to the directory to patch
# set the VERSION variable to the current version
# call
# return 0 if PATCH_VERSION is set
# return 1 if PATCH_VERSION is not set
# return -1 if error
get_patch_version () {

if [[ "x""$VERSION" == "x" ]]; then
  echo "Error: VERSION not set prior to calling $0"
  return -1
fi

# Get the current patch version of the current ss3 directory

GET_PATCH_VERSION_DIR=$( pwd )

echo "Finding patch version."

PATCH_VERSION="0"

while true; do

# file should include the version number
  if [[ -f "$GET_PATCH_VERSION_DIR"'/.patch-'"$VERSION"'-'"$(( $PATCH_VERSION + 1 ))" ]]; then
    PATCH_VERSION=$(( $PATCH_VERSION + 1 ))
  else
    break
  fi

done
    
cd "$GET_PATCH_VERSION_DIR"
if [[ "x""$PATCH_VERSION" == "x0" ]]; then
  echo "No patches applied yet."
  return 1
else
  echo "At patch version $PATCH_VERSION"
  return 0
fi

}


# cd to the ss3 directory to patch
# set the VERSION variable to the current ss3 version
# set the PATCH_VERSION variable to the current patch version
# call
# return 0 if patch available
# return 1 if no patch available 
# return -1 if error
patch_check () {

if [[ "x""$VERSION" == "x" ]]; then
  echo "Error: VERSION not set prior to calling $0"
  return -1
fi
if [[ "x""$PATCH_VERSION" == "x" ]]; then
  echo "Error: PATCH_VERSION not set prior to calling $0"
  return -1
fi

# Check for new patches for the current ss3 directory

PATCH_CHECK_DIR=$( pwd )

echo "Checking for new patches."

#Change signstream url based on version tag provided in version file
SIGNSTREAM_PATCH_FN='SignStream3-'"$VERSION"'-patch-'"$(( $PATCH_VERSION + 1 ))"'.zip'
SIGNSTREAM_PATCH_URL='http://dai.cs.rutgers.edu/SignStream/download/release/patches/'"$SIGNSTREAM_PATCH_FN"

if curl -L --range 0-0 --silent --fail --output /dev/null "$SIGNSTREAM_PATCH_URL"; then
  echo "New patches exist."
  cd "$PATCH_CHECK_DIR"
  return 1
else
  echo "No new patches exist."
  echo ""
  cd "$PATCH_CHECK_DIR"
  return 0
fi

}


# cd to the directory to patch
# set the VERSION variable to the current version
# set the PATCH_VERSION variable to the current patch version
# return 1 if no patch needed
# return 0 if patch applied
# return -1 if error
#
# This will not pre-check if patches are available
#
patch () {

if [[ "x""$VERSION" == "x" ]]; then
  echo "Error: VERSION not set prior to calling $0"
  return -1
fi
if [[ "x""$PATCH_VERSION" == "x" ]]; then
  echo "Error: PATCH_VERSION not set prior to calling $0"
  return -1
fi

# Patch the current ss3 directory

PATCH_DIR=$( pwd )

echo "Patching"


# Patching

ORIG_PATCH_VERSION=$PATCH_VERSION

while true; do

  #Change signstream url based on version tag provided in version file
  SIGNSTREAM_PATCH_FN='SignStream3-'"$VERSION"'-patch-'"$(( $PATCH_VERSION + 1 ))"'.zip'
  SIGNSTREAM_PATCH_URL='http://dai.cs.rutgers.edu/SignStream/download/release/patches/'"$SIGNSTREAM_PATCH_FN"

  SIGNSTREAM_PATCH_REQUEST=$( curl -L --silent --write-out "HTTPSTATUS:%{http_code}" --output "$SIGNSTREAM_PATCH_FN" "$SIGNSTREAM_PATCH_URL" )

  if [ "x"$( echo "$SIGNSTREAM_PATCH_REQUEST" | grep '^HTTPSTATUS:'  | sed -e 's/HTTPSTATUS://' ) != "x200" ]; then
    if [ "x""$PATCH_VERSION" == "x""$ORIG_PATCH_VERSION" ];then
      if [[ -f "$SIGNSTREAM_PATCH_FN" ]]; then
        rm -rf "$SIGNSTREAM_PATCH_FN"
      fi
      echo "No patches found"
      return 1
    else
      if [[ -f "$SIGNSTREAM_PATCH_FN" ]]; then
        rm -rf "$SIGNSTREAM_PATCH_FN"
      fi
      echo "No more patches found"
    fi
    break
  else
    PATCH_VERSION=$(( $PATCH_VERSION + 1 ))
    echo "Found patch $PATCH_VERSION"

    #Unzip Latest Version of SignStream.
    echo "Unzipping the new version..."
    unzip -o -q "$SIGNSTREAM_PATCH_FN"
    if [ "$?" != "0" ]; then
      PATCH_VERSION=$(( $PATCH_VERSION - 1 ))
      echo "An error occurred while unzipping a patch for the new version of SignStream3. Please contact the administrator."
      echo "Cleaning up..."
      rm -rf "$SIGNSTREAM_PATCH_FN"
      cd "$PATCH_DIR"
      close
    fi

    #Delete the zipped version
    rm -rf "$SIGNSTREAM_PATCH_FN"

    # In future may need to run script after patch is downloaded.
    PATCH_COMMAND='Patch-'$VERSION'-'$PATCH_VERSION'.command'
    if [ -f "$PATCH_COMMAND" ]; then
      ./"$PATCH_COMMAND"
    fi

    echo "Applied patch $PATCH_VERSION"

  fi

done

echo "Done."
echo ""

if [[ "x""$ORIG_PATCH_VERSION" != "x""$PATCH_VERSION" ]]; then
  echo "You may need to manually restart SignStream3 for the patches to apply."

  return 1
else
  return 0
fi

}

download_new () {


DOWN_DIR=$( pwd )

#Sanity Check
if [[ "x""$TMP_DIR" == "x""$DIR" ]]; then
    echo "You can not update a SignStream3 version in a temporary working directory."
    echo "SignStream3 has NOT been updated.  Contact the System Administrator." 
    close
fi

# Probably should error and exit.  But assuming it is safe to delete old temp directories.
if [ -d "$TMP_DIR" ]; then
  echo "Temporary directory $TMP_DIR already exists."
  echo "Deleting it."
  rm -rf "$TMP_DIR"
fi	

mkdir -p "$TMP_DIR"

if [ ! -d "$TMP_DIR" ]; then
  echo "An error has occured.  Could not create the temporary directory $TMP_DIR"
  echo "SignStream3 has NOT been updated.  Contact the System Administrator." 
  close
fi	

cd "$TMP_DIR"


#Change signstream url based on version tag provided in version file
NEW_SIGNSTREAM_FN='SignStream3-'"$NEW_VERSION"'.zip'
NEW_SIGNSTREAM_URL='http://dai.cs.rutgers.edu/SignStream/download/release/'"$NEW_SIGNSTREAM_FN"


echo ""

#Download the new version of SignStream version from DAI.
echo "Downloading the $NEW_VERSION version of SignStream3..."
echo "Please be patient."

NEW_SIGNSTREAM_REQUEST=$( curl -L --silent --write-out "HTTPSTATUS:%{http_code}" --output "$NEW_SIGNSTREAM_FN" "$NEW_SIGNSTREAM_URL" )
if [ "x"$( echo "$NEW_SIGNSTREAM_REQUEST" | grep '^HTTPSTATUS:'  | sed -e 's/HTTPSTATUS://' ) != "x200" ]; then
    echo "An error occurred while downloading the new version of SignStream3."
    echo "Please make sure you have sufficient space to download the file,"
    echo "have file permissions to the SignStream3 and the $TMP_DIR directories,"
    echo "and have a working internet connection."
    echo "Cleaning up..."
    cd "$DOWN_DIR"
    rm -rf "$TMP_DIR"
    close
fi

echo "Done."
echo ""

#Unzip Latest Version of SignStream.
echo "Unzipping the new version..."
unzip -q "$NEW_SIGNSTREAM_FN"
if [ "$?" != "0" ]; then
    echo "An error occurred while unzipping the new version of SignStream3. Please contact the administrator."
    echo "Cleaning up..."
    cd "$DOWN_DIR"
    rm -rf "$TMP_DIR"
    close
fi

#Delete the zipped version
rm -rf "$NEW_SIGNSTREAM_FN"



if [ -d "SignStream3" ]; then 
    #Use the directory name
    NEW_SIGNSTREAM_DIR="$TMP_DIR"'/'"SignStream3"
    NEW_SIGNSTREAM_DIR="$TMP_DIR"'/'"SignStream3"
else
  if [ -d 'SignStream3-'"$NEW_VERSION" ]; then
    #Use the directory name with the new version appended
    NEW_SIGNSTREAM_DIR="$TMP_DIR"'/SignStream3-'"$NEW_VERSION"
  else
    echo "An error occurred while upgrading SignStream3. Please contact the administrator."
    echo "Cleaning up..."
    cd "$DOWN_DIR"
    rm -rf "$TMP_DIR"
    close
  fi
fi


cd $NEW_SIGNSTREAM_DIR

VERSION=$NEW_VERSION
get_patch_version
patch

cd "$DOWN_DIR" 

}


cleanup_download () {

# this is only called from the "ALL" pathway - therefore SRC_DIR and DEST_DIR are never set

CLEAN_DIR=$( pwd )

if [[ "x""$CLEAN_DIR" == "x""$TMP_DIR" ]]; then
 
  echo "Couldn't clean up $TMP_DIR"
  echo "You must manually delete this working directory on your own"

else

  echo "Finishing and cleaning up..."

  rm -rf "$TMP_DIR"

fi


}




update_dest() {

EXCLUDE_BACKUP_DIR="$BACKUP_DIR"

# "Upgrade"
verbetween "3.0.0" "$DEST_VERSION" "3.3.0"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then # "3.0.0"<=DEST_VERSION<3.3.0

  vercomp "3.3.0" "$SRC_VERSION"
  if [[ "$?" -ne 1 ]]; then # SRC_VERSION >= 3.3.0

    if [ -d "$DEST_DIR"'/signstream-backup' ] && [ ! -d "$DEST_DIR"'/signstream3-backup' ]; then
      mv "$DEST_DIR"'/signstream-backup' "$DEST_DIR"'/signstream3-backup'
    fi

  fi

fi


verbetween "3.0.0" "$DEST_VERSION" "3.2.10"
if [[ "$?" -eq 4 ]]; then # $DEST_VERSION<3.0.0
  echo "Ignoring SignBank." 

elif [[ "$?" -eq 2 || "$?" -eq 0 ]]; then # 3.0.0<=$DEST_VERSION<3.2.10

  DEST_SIGNBANK_ORIGINAL_MD5="57ec1b3819fc82876e2572c53d92cfde"

fi

verbetween "3.2.10" "$DEST_VERSION" "3.3.0"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then # 3.2.10<=$DEST_VERSION<3.3.0

  DEST_SIGNBANK_ORIGINAL_MD5="04f17a1b59b42d16a6246ec7053e11ce"

fi
  
verbetween "3.3.0" "$DEST_VERSION" "3.3.6"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then # 3.3.0<=$DEST_VERSION<3.3.6
  DEST_SIGNBANK_ORIGINAL_MD5=$( cat "$DEST_DIR"'/SignStream3.app/Contents/Info.plist' | grep -A 1 '<key>SIGN_BANK_ORIGINAL_MD5</key>' | grep '.*<string>.*</string>.*' | sed -e 's/.*<string>\(.*\)<\/string>.*/\1/' )
fi

vercomp "3.3.6" "$UPDATE_COMMAND_MAX_VERSION"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then

  verbetween "3.3.6" "$DEST_VERSION" "$UPDATE_COMMAND_MAX_VERSION"
  if [[ "$?" -eq 2 || "$?" -eq 0 || "$?" -eq 1 ]]; then # 3.3.6<=$DEST_VERSION<=maxversion
    DEST_SIGNBANK_ORIGINAL_MD5=$( sed -n 's/signbank_md5 \(.*\)$/\1/p' "$DEST_DIR"'/'"$INFO_FILE" )
  fi

fi

# No longer needed.
#
## "Downgrade"
#vercomp "3.3.0" "$DEST_VERSION"
#if [[ "$?" -ne 1 ]]; then # DEST_VERSION >= 3.3.0
#
#  verbetween "3.0.0" "$SRC_VERSION" "3.3.0"
#  if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then # "3.0.0"<=SRC_VERSION<3.3.0
#
#    if [ -d "$DEST_DIR"'/signstream3-backup' ] && [ ! -d "$DEST_DIR"'/signstream-backup' ]; then
#      mv "$DEST_DIR"'/signstream3-backup' "$DEST_DIR"'/signstream-backup'
#    fi
#    EXCLUDE_BACKUP_DIR="signstream-backup"
#
#  fi
#fi

#Move all non-local files over.
echo ""
echo "Updating SignStream3..."

if [ "x""$( md5 -q "$DEST_DIR"'/signbank/globalSignBank.xml' )" == "x""$DEST_SIGNBANK_ORIGINAL_MD5" ]; then
  cp -a "$SRC_DIR"'/signbank/globalSignBank.xml' "$DEST_DIR"'/signbank/globalSignBank.xml'
fi

# Hack to copy over even old files.
# Delete destination files that aren't excluded.
# Then re-sync.

mkdir -p "$SRC_DIR"'/.tmp'
if [ -e "$SRC_DIR"'/.tmp' ]; then
  /usr/bin/rsync -rl --exclude=SignStreamDatabases --exclude=SignStreamLog.txt --exclude="$EXCLUDE_BACKUP_DIR" --exclude='/newXMLfiles/*local*' --exclude='/signbank/*SignBank*' "$SRC_DIR"'/.tmp/' "$DEST_DIR"'/' --delete
else
  echo "Something went wrong. Contact you System Administrator."
  close
fi
rmdir "$SRC_DIR"'/.tmp'

/usr/bin/rsync -rl --exclude=SignStreamDatabases --exclude=SignStreamLog.txt --exclude="$EXCLUDE_BACKUP_DIR" --exclude='/newXMLfiles/*local*' --exclude='/signbank/*SignBank*' "$SRC_DIR"'/' "$DEST_DIR"'/' --delete

echo "Signstream has been updated."

}


backup () {

#Sanity Check
if [ -d "$BACKUP_DIR_DATE" ]; then
  echo "Problem.  Date stamped backup directory exists when none should."
  echo "Exiting."
  close
fi

if [ -d "$BACKUP_DIR" ]; then
  yn="y"
  echo "There appears to already be a backup of SignStream3."
  echo "It is saved in the directory $BACKUP_DIR."
  echo "You can keep the existing backup...or...replace it with a new backup."
  echo "Do you want to replace the existing backup with a new one?"
  echo "(Please answer \"yes\" or \"no\")"

  while true; do
    read -p "" yn
    if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
      echo "You answered \"yes\". The existing backup will be replaced with a new one.";
      break;
    elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
      echo "You answered \"no\". The existing backup will be kept."
      echo "No new backup will be created.";
      break;
    else
      echo "Please answer \"yes\" or \"no\".";
    fi
  done
  #Keep the old backup and leave.
  if [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
    return
  fi
  #Remove the old backup.
  rm -rf "$BACKUP_DIR"
fi

#Replace or keep the existing backup.
rm -rf "$BACKUP_DIR_DATE"

#Backup existing version of SignStream.
echo ""
echo "Backing up the Current Version of SignStream3..."
echo "Please be patient"

mkdir -p "$BACKUP_DIR_DATE"
tar --exclude="$BACKUP_DIR" --exclude="$BACKUP_DIR_DATE" --exclude="$BACKUP_DIR_DATE"'/'"$BACKUP_FN_DATE" -czpf "$BACKUP_DIR_DATE"'/'"$BACKUP_FN_DATE" .
mv "$BACKUP_DIR_DATE" "$BACKUP_DIR"

echo "Done."
echo ""

echo "A pre-update backup has be placed in the directory $BACKUP_DIR"
echo ""


}


rename_dest_directory () {
DEST_DIR_BASENAME=`basename $DEST_DIR`
DEST_DIR_DIRNAME=`dirname $DEST_DIR`
NEW_DEST_DIR="$DEST_DIR_DIRNAME"'/SignStream3' 
if [ "$DEST_DIR" != "$NEW_DEST_DIR" ]; then
  if [ ! -d "$NEW_DEST_DIR" ]; then
    mv "$DEST_DIR" "$NEW_DEST_DIR"
    echo ""
    echo "SignStream3 was installed here: $DEST_DIR"
    echo "This directory was renamed to: $NEW_DEST_DIR"
    DEST_DIR="$NEW_DEST_DIR"
  else
    echo ""
    echo "SignStream3 is installed here: $DEST_DIR"
    echo "You may want to rename this directory to just 'SignStream3'" 
    echo ""
  fi
fi

}


stop_ss3 (){

VERSION=$( ./Update.command --version )

vercomp "3.0.0" "$UPDATE_COMMAND_MAX_VERSION"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then

 verbetween "3.0.0" "$VERSION" "$UPDATE_COMMAND_MAX_VERSION"
 if [[ "$?" -eq 2 || "$?" -eq 0 || "$?" -eq 1  ]]; then
  # version between 3.0.0 and $UPDATE_COMMAND_MAX_VERSION 

  verbetween "3.0.0" "$VERSION" "3.3.6"
  if [[ "$?" -eq 2 || "$?" -eq 0  ]]; then
    # version between 3.0.0 and < 3.3.6

    SS3_WAS_RUNNING=`osascript -e 'tell application "System Events"
(get name of every application process) contains "JavaApplicationStub"
end tell
'`
    if [[ "x""$SS3_WAS_RUNNING" == 'xtrue' ]]; then
      echo "Closing SignStream to Update... (You may be asked to save changes before closing)"
      echo ""
      #Close SignStream
      osascript -e 'quit app "SignStream3"'
      touch $STOPPED_FILE
    fi
  fi

  vercomp "3.3.6" "$UPDATE_COMMAND_MAX_VERSION"
  if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then

  verbetween "3.3.6" "$VERSION" "$UPDATE_COMMAND_MAX_VERSION"
  if [[ "$?" -eq 2 || "$?" -eq 0 || "$?" -eq 1  ]]; then
    # version between 3.3.6 and $UPDATE_COMMAND_MAX_VERSION 

    SS3_WAS_RUNNING=`osascript -e 'tell application "System Events"
(get name of every application process) contains "'"$SIGNSTREAM_PROCESS_NAME"'"
end tell
'`
    if [[ "x""$SS3_WAS_RUNNING" == 'xtrue' ]]; then
      echo "Closing SignStream to Update... (You may be asked to save changes before closing)"
      echo ""
      #Close SignStream
      osascript -e 'quit app "SignStream3"'
      touch $STOPPED_FILE
    fi
  fi

  fi

 elif [[ "$?" -eq 4 ]]; then
  # version less than 3.0.0

  echo "Version is below the min version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

 elif [[ "$?" -eq 3 ]]; then 
  # version more than $UPDATE_COMMAND_MAX_VERSION 

  echo "Version is beyond the max version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

 fi

else

  echo "Version is below the min version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

fi

}


restart_ss3(){

VERSION=$( ./Update.command --version )

vercomp "3.0.0" "$UPDATE_COMMAND_MAX_VERSION"
if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then

 verbetween "3.0.0" "$VERSION" "$UPDATE_COMMAND_MAX_VERSION"
 if [[ "$?" -eq 2 || "$?" -eq 0 || "$?" -eq 1  ]]; then
  # version between 3.0.0 and $UPDATE_COMMAND_MAX_VERSION 

  if [[ "x""$SS3_WAS_RUNNING" == 'xtrue' || -f $STOPPED_FILE ]]; then
    echo ""
    echo "Relaunching SignStream3..."
    open -g "./SignStream3.app"
    echo "Done."
    echo ""
    rm -f $STOPPED_FILE
  fi

 elif [[ "$?" -eq 4 ]]; then
  # version less than 3.0.0

  echo "Version is beyond the max version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

 elif [[ "$?" -eq 3 ]]; then 
  # version more than $UPDATE_COMMAND_MAX_VERSION 

  echo "Version is below the min version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

 fi

else

  echo "Version is below the min version of this script"
  echo "Unable to see if SignStream3 is still running,"
  echo "Nor stop it if it was."

fi

}


main() {
# ACTION = PATCH
if [[ "x""$ACTION" == "xPATCH" ]]; then

  cd "$DIR"
  get_current_version
  VERSION="$CURRENT_VERSION"
  get_patch_version
  patch
  cd "$ORIG_DIR"

# ACTION = ALL
elif [[ "x""$ACTION" == "xALL" ]]; then


  echo ""
  echo "Starting Update Process for SignStream3"
  echo ""

  # Set the variable CURRENT_VERSION
  cd "$DIR"
  get_current_version

  if [[ "x""$CURRENT_VERSION" == "x" ]]; then
    echo "Can not determine the current version."
    echo "Contact your system administrator for help."
    close
  fi

  vercomp "3.0.0" "$UPDATE_COMMAND_MAX_VERSION"
  if [[ "$?" -eq 2 || "$?" -eq 0 ]]; then

  verbetween "3.0.0" "$CURRENT_VERSION" "$UPDATE_COMMAND_MAX_VERSION"
  if [[ "$?" -eq 4 ]]; then
    echo "The current version of SignStream3 is $CURRENT_VERSION."
    echo "This script will only work with SignStream version 3.0.0 or higher."
    echo "Contact your system administrator for help."
    close
  elif [[ "$?" -eq 3 ]]; then
    echo "The current version of SignStream3 is $CURRENT_VERSION."
    echo "This script will only work with SignStream version up to $UPDATE_COMMAND_MAX_VERSION"
    echo "Contact your system administrator for help."
    close
  fi

  else

    echo "The current version of SignStream3 is $CURRENT_VERSION."
    echo "This script will only work with SignStream version 3.0.0 or higher."
    echo "Contact your system administrator for help."
    close

  fi

  # Check for Patches and Patch if desired.
  VERSION="$CURRENT_VERSION"
  get_patch_version
  echo "Checking if new patches exist."
  patch_check
  if [[ "$?" -eq 1 ]]; then
    yn="y"
    echo ""
    echo "There appears to be patches available."
    echo "It is recommended you patch your software before upgrading"

    if [[ "x""$FORCE_PATCH" != "xtrue" ]]; then

    echo "Do you want to patch now? (Please answer \"yes\" or \"no\")"

    while true; do
      read -p "" yn
      if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
        echo "You answered \"yes\". Your software will be patched prior to upgrading.";
        break;
      elif [[ "$yn" =~ ^(N|n|NO|No|no)$ ]]; then
        echo "You answered \"no\". Your software will not be patched prior to upgrading.";
        break;
      else
        echo "Please answer \"yes\" or \"no\".";
      fi
    done

    fi # if [[ "x""$FORCE_PATCH" != "xtrue" ]]
    
    if [[ "$yn" =~ ^(Y|y|YES|Yes|yes)$ ]]; then
      patch
      echo "Patching complete."
      echo "Rerunning $ORIG_CMD ${ORIG_ARGS[@]}"
      cd "$ORIG_DIR"
      "$ORIG_CMD" "${ORIG_ARGS[@]}"
      exit "$?"
    fi
  fi


  # Set the variable NEW_VERSION
  cd "$DIR"
  get_new_version


  # Check if NEW_VERSION exists on the server
  cd "$DIR"
  verify_new_version_exists

  vercomp "$NEW_VERSION" "3.0.0"
  if [[ "$?" -eq 2 ]]; then
    echo "The new version of SignStream3 requested is $NEW_VERSION."
    echo "This script will only work with SignStream version 3.0.0 or higher."
    echo "Contact your system administrator for help."
    close
  fi


  # Ask the user if they want to install the new version over the current version
  cd "$DIR"
  confirm_update


  # Download the new version and apply any patches
  cd "$DIR"
  download_new


  # Run the copy using the newer of the two update scripts.
  vercomp "$CURRENT_VERSION" "$NEW_VERSION"

  # If versions are the exact same, or current is newer, continue using this current script
  # If new version is newer than the current version, use that one
  if [[ "$?" -ne 1 ]]; then
    cd "$NEW_SIGNSTREAM_DIR"
  else
    cd "$DIR"
  fi


  if [[ "x""$ORIG_DIR" == "x""$DIR" ]]; then
    SYNC_ORIG_DIR_TO_DIR=true
  else
    SYNC_ORIG_DIR_TO_DIR=false
  fi

  # All versions 3.3.0 or higher should support this.
  ./Update.command --source "$NEW_SIGNSTREAM_DIR" --destination "$DIR" 

  if ! [ -e "$DIR" ]; then
    DIR_DIRNAME=`dirname "$DIR"`
    NEW_DIR="$DIR_DIRNAME""/SignStream3"
    if [ -e "$NEW_DIR" ]; then
      DIR="$NEW_DIR"
    fi
  fi

  if [[ "x""$SYNC_ORIG_DIR_TO_DIR" == "xtrue" ]]; then
    ORIG_DIR="$DIR"
  fi

  cd "$DIR"

  cleanup_download

  echo ""
  echo "SignStream3 Updated Successfully."

  close

# ACTION = UPDATE
elif [[ "x""$ACTION" == "xUPDATE" ]]; then


  if [[ "x""$ORIG_DIR" == "x""$DEST_DIR" ]]; then
    SYNC_ORIG_DIR_TO_DEST_DIR=true
  else
    SYNC_ORIG_DIR_TO_DEST_DIR=false
  fi


  # Get source version
  cd "$SRC_DIR"
  
  SRC_VERSION=$( ./Update.command --version )
 
  vercomp "$SRC_VERSION" "3.0.0"
  if [[ "$?" -eq 2 ]]; then # SRC_VERSION<3.0.0
    echo "The source version of SignStream3 is $DEST_VERSION."
    echo "This script will only work with SignStream version 3.0.0 or higher."
    echo "Contact your system administrator for help."
    close
  fi

  # Get destination version
  cd "$DEST_DIR"
  
  DEST_VERSION=$( ./Update.command --version )

  vercomp "$DEST_VERSION" "3.0.0"
  if [[ "$?" -eq 2 ]]; then # DEST_VERSION<3.0.0
    echo "The destination version of SignStream3 is $DEST_VERSION."
    echo "This script will only work with SignStream version 3.0.0 or higher."
    echo "Contact your system administrator for help."
    close
  fi
  stop_ss3
  

  # based on the destination version, back it up.
  cd "$DEST_DIR"
  ./Update.command --backup


  cd "$SRC_DIR"
  update_dest

  # This needs to run after the update.
  # This should now work even for old version given the automatic patch download.
  # No need for autoclose "--from_signstream3_update should 
  # imply all options needed for this update script
  cd "$DEST_DIR"
  ./"$SIGNBANK_UPDATE_COMMAND" --from_signstream3_update


  cd "$DEST_DIR"
  ./"$DISABLE_QUARANTINE_COMMAND" --noautoclose


  cd "$SRC_DIR"
  rename_dest_directory
  
  if [[ "x""$SYNC_ORIG_DIR_TO_DEST_DIR" == "xtrue" ]]; then
    ORIG_DIR="$DEST_DIR"
  fi  

  # based on the destination and source versions perform the following actions
  # currently running should be the destination version.
  # would be better if we have a local script that gave us this information.
  # like SignStream3.app --running
  cd "$DEST_DIR"
  restart_ss3

  cd "$ORIG_DIR"


# ACTION = VERSION
elif [[ "x""$ACTION" == "xVERSION" ]]; then
  
  cd "$DIR"
  get_current_version
  echo "$CURRENT_VERSION"
  cd "$ORIG_DIR"
  exit

# ACTION = BACKUP
elif [[ "x""$ACTION" == "xBACKUP" ]]; then

  cd "$DIR"
  backup
  cd "$ORIG_DIR"
  exit
 
else

  echo "An error occured"
  exit

fi

}

main

