#!/bin/bash
# tbus_installer.sh - A utility script to install the tbus extension for VSimRTI.
# Ensure this file is executable via chmod a+x tbus_installer.sh
#
# author: <goebel@cs.uni-duesseldorf.de>
# last updated: 11/11/2015
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

set -o nounset
set -o errtrace
set -o errexit
set -o pipefail

#trap clean_up EXIT

cyan="\033[01;36m"
red="\033[01;31m"
bold="\033[1m"
restore="\033[0m"

arg_install_omnet=true
arg_omnet_tar=""
arg_vsimrtipath=""
arg_remove_sources=true
BASE_URL="https://wwwcn.cs.uni-duesseldorf.de/software/tbus"
SCENARIO_URL="$BASE_URL/scenarios0.15.0"
OMNET_STARTER="start-omnet-federate.sh"
TBUS_VSIMRTI_PATCH="tbus-vsimrti-0.15.patch"
OMNET_INSTALLER="omnet_installer_tbus.sh"
TBUS_VSIMRTI="tbus-vsimrti.tgz"
DEFAULTS_XML_PATCH="defaults.xml.patch"
SCENARIO_ETSI="Taubental-large-etsi.tgz"
SCENARIO_ENHANCED="Taubental-large.tgz"
PATCHED_EMBASSADOR="http://www.dcaiti.tu-berlin.de/research/simulation/download/get/omnetpp-ambassador-1.1.2b.jar"

arg_quiet=false

log() {
   printf "$*\n"
   #echo "$*\n"
   return $?
}

check_shell() {
   if [ -z "$BASH_VERSION" ]; then
      fail "This script requires the BASH shell"
      exit 1
   fi
}

fail() {
   log "${bold}${red}\nERROR: $*\n${restore}"
   exit 1
}

has() {
   return $( which $1 >/dev/null )
}

get_arguments() {
    log "Argumentlist:"
    log "'$*'"
    if [ "$#" > 1 ]; then
      if [ "${1:-}" == "-h" ] || [ "${1:-}" == "--help" ]; then
         print_usage
         exit 0
      else
        # note: if this is set to > 0 the /etc/hosts part is not recognized ( may be a bug )
        while [[ $# > 1 ]]
        do
            key="$1"

            case $key in
                -p|--path-to-vsimrti)
                    arg_vsimrtipath="$(readlink -e $2)" || fail "readlink not installed or vsimrtipath not set correctly $2"
                    log "VSimRTIPath = $arg_vsimrtipath"
                    shift # remove argument
                    ;;
                -t|--omnet_tar)
                    arg_omnet_tar="$(readlink -e $2)"  || fail "readlink not installed or omnettar not found $2"
                    log "omnet_tar at = $arg_omnet_tar"
                    shift # past argument
                    ;;
                -n|--do_not_call_omnet_installer)
                    arg_install_omnet=false
                    log "Not calling OMNeT++ installer"
                    ;;
                    
                -d|--do_not_remove_sources)
                    arg_remove_sources=false
                    ;;
            esac
            shift # past argument or value
        done
      fi
    fi
    if [ "$arg_omnet_tar" == "" ]; then
      fail "Please provide at least the path to the tbus installer tar \n./tbus_installer.sh -t /path/to/omnetpp-src.tgz\n\nHint: Use -h or --help to list the options."
      exit 1
    fi
    if [ "$arg_vsimrtipath" == "" ] ; then
      fail "Please provide at least the path to the vsimrti 0.15 installation you want to patch for tbus usage.\n-p /path/to/vsimrti-directory\n"
      exit 1
    fi
    if [ ! -f "$arg_vsimrtipath/vsimrti.sh" ]; then
      fail "The provided path to vsimrti seems to be wrong. Please provide at least the path to the vsimrti 0.15 installation you want to patch for tbus usage.\n-p /path/to/vsimrti-directory\n"
      exit 1
    fi
}

print_usage() {
   log "${bold}${cyan}[$(basename "$0")] -- Installation script for OMNeT++/INETMANET and TBUS for VSimRTI${restore}"
   log "\nUsage: $0 [arguments]"
   log "\nArguments:"
   log "\n -t, --omnet_tar <path to omnet src archive>"
   log "\n -p, --path-to-vsimrti <path to the vsrimrti 0.15 folder containing vsimrti.sh"
   log "\nYou can obtain the omnet tar from ${cyan}https://omnetpp.org/component/jdownloads/download/32-release-older-versions/2272-omnet-4-4-1-source-ide-tgz${restore}"
   log "\nVSimRTI can be obtained from ${cyan}http://www.dcaiti.tu-berlin.de/research/simulation/download/get/vsimrti-bin-0.15.0.zip${restore}"
}

print_info() {
   log "${bold}${cyan}[$(basename "$0")] -- Installation script for OMNeT++/INETMANET and TBUS for VSimRTI${restore}"
   log "\nNorbert Goebel <goebel@cs.uni-duesseldorf.de> based on the omnet_installer.sh script by the VSimRTI developer team <vsimrti@fokus.fraunhofer.de>"
   log "\nThis shell script will:"
   log " - install the OMNeT++ network simulator with the INETMANET and the TBUS library"
   log " - install example scenarios for TBUS simulations"
   log " - disable the automatic deployment of the omnetpp-federate by vsimrti in etc/defaults.xml"
   log " - install the start-omnet-federate.sh script to manually start the omnetpp-federate with libtbus support"
   log "\nIf there is an error (like a missing package) during the installation, the output may give hints about what went wrong.\n"
   if [ "$arg_quiet" = false ]; then
      read -p "Press any key to continue or CTRL+C to abort" -n1 -s
      log "\n"
   fi
}

download() {
   if [ ! -f "$(basename "$1")" ]; then
      if has wget; then
         wget -q "$1" || fail "The download URL seems to have changed. File not found: "$1"";
      elif has curl; then
         curl -s -O "$1" || fail "The download URL seems to have changed. File not found: "$1"";
      else
         fail "Can't download "$1".";
      fi
   else
      fail "File $(basename "$1") already exists."
   fi
}

download_and_unpack_scenarios() {
  log "Downloading and unpacking tbus example scenarios Taubental"
  cd "$arg_vsimrtipath/scenarios"
  download "$SCENARIO_URL/$SCENARIO_ETSI" 
  download "$SCENARIO_URL/$SCENARIO_ENHANCED"
  tar -xzf "$SCENARIO_ETSI" || fail "Extraction of $SCENARIO_ETSI failed."
  tar -xzf "$SCENARIO_ENHANCED" || fail "Extraction of $SENARIO_ENHANCED failed."
  rm "$SCENARIO_ETSI"
  rm "$SCENARIO_ENHANCED"
}

download_tbus_omnet_script(){
  log "Downloading startscript $OMNET_STARTER for manual OMNeT++ startup with libtbus"
  cd $arg_vsimrtipath
  download "$BASE_URL/$OMNET_STARTER"
  chmod +x "$OMNET_STARTER"
}

download_new_vsimrti_config(){
  log "Patching etc/defaults.xml to disable automatic omnetpp deployment"
  cd "$arg_vsimrtipath/etc/"
  cp defaults.xml defaults.xml.bak
  download "$BASE_URL/$DEFAULTS_XML_PATCH"
  patch -p1 defaults.xml < $DEFAULTS_XML_PATCH || fail "Patching defaults.xml in $arg_vsimrtipath/etc/ failed."
}

download_omnet_installer(){
  log "Downloading modified omnetpp vsimrti installer and tbus patches"
  cd "$arg_vsimrtipath/bin/fed/omnetpp"
  chmod -x omnet_installer.sh
  mv omnet_installer.sh omnet_installer.sh.do_not_use
  download "$BASE_URL/$OMNET_INSTALLER"
  chmod +x $OMNET_INSTALLER
  download "$BASE_URL/$TBUS_VSIMRTI_PATCH"
  download "$BASE_URL/$TBUS_VSIMRTI"
  download "$PATCHED_EMBASSADOR"
}

#store the current working dir

check_shell

get_arguments $*

print_info

download_and_unpack_scenarios

download_tbus_omnet_script

download_new_vsimrti_config

download_omnet_installer

log "\n\n${bold}${cyan}Finished downloading all tbus patches and prerequesites.${restore}"

log "\nThe installation and compilation of OMNeT++/INETMANET and TBUS will continue by "
log "calling the script $arg_vsimrtipath/bin/fed/omnetpp/$OMNET_INSTALLER"
log "The compilation will take some time!"

read -p "Press any key to continue or CTRL+C to abort" -n1 -s

if [ "$arg_install_omnet" = true ]; then
  ./$OMNET_INSTALLER -d -t $arg_omnet_tar 
else
  log "\nParameter -ni found, please install omnet by hand calling:"
  log "${bold}${cyan}./${OMNET_INSTALLER} -d -t ${arg_omnet_tar}${restore}"
  log "in $(pwd)"
fi
