#!/bin/sh


#########################
# Environment Variables #
#########################

if [ -x /usr/bin/echo ] ; then
   echo=/usr/bin/echo
elif [ -x /bin/echo ] ; then
   echo=/bin/echo
else
   echo=echo
fi


#############
# Functions #
#############

###########################################################################
#
#  detect_host
#    Identify the host on which this script is running.  In the event the
#    host can not be identified, print out an error message to the user.
#
###########################################################################

detect_host () {
   hosttype=`uname`
   case "$hosttype" in
       OSF1) $echo "Error: The application cannot be run on this host: $hosttype."
             exit
             ;;

      SunOS) proc_type=`uname -p` 
             if [ "$proc_type" = "sparc" ] ; then
                platform="s64"
             elif [ "$proc_type" = "i386" ] ; then
                platform="sax"
             else
                $echo "Error: The application cannot be run on this host: $hosttype."
                exit
             fi
             ;;

      HP-UX) model_type=`model`
             if [ "`set -f ; $echo $model_type | sed -n '/ia64/ {p;}'`" ] ; then
                platform="h6i"
             else
                platform="h64"

                if [ $SHLIB_PATH ] ; then
                   unset SHLIB_PATH
                fi
             fi
             ;;

      Linux) machine_type=`uname -m`
             if [ "$machine_type" = "x86_64" ] ; then
                platform="lax"
             elif [ "$machine_type" != "ia64" ] ; then
                platform="lnx"
             else
                $echo "Error: The application cannot be run on this host: $hosttype."
                exit
             fi
             ;;

        AIX) platform="r64"
             ;;

     Darwin) proc_type=`uname -p`
             if [ "$proc_type" = "powerpc" ] ; then
                platform="mpp"
             elif [ "$proc_type" = "i386" ] ; then
                if [ "`sysctl -n hw.optional.x86_64 2> /dev/null`" = 1 ] ; then
                   platform="m64"
                else
                   platform="mac"
                fi
             else
                $echo "Error: The application cannot be run on this host: $hosttype."
                exit
             fi
             ;;

          *) $echo "Error: Cannot determine the current platform."
             exit 2
             ;;
   esac
}

###########################################################################
#
#  locate_data_file
#    Locate the data file associated with the script passed in.  A value
#    is only returned from this function if a valid data file is found to
#    exist for use by the script.
#
###########################################################################
locate_data_file () {
   script=$1
   extension=$2

   dir="`dirname "$script"`"
   base="`basename "$script"`"

   file="$dir/`set -f ; $echo "$base" | sed 's/^\([^\.]*\).*$/\1/'`$extension"

   if [ ! -f "$file" ] ; then
      if [ "`set -f ; $echo $base | sed -n '/^[^\.]*_console\..*$/ {p;}'`" ] ; then
         file="$dir/`set -f ; $echo "$base" | sed 's/^\([^\.]*\)_console\..*$/\1/'`$extension"
      elif [ "`set -f ; $echo $base | sed -n '/^[^\.]*_console$/ {p;}'`" ] ; then
         file="$dir/`set -f ; $echo "$base" | sed 's/^\([^\.]*\)_console$/\1/'`$extension"
      fi
   fi

   if [ ! -f "$file" ] ; then
      file=""
   fi

   $echo $file
   return
}

###########################################################################
#
#  load_data
#    Load all of the data in the given section of a given file.  After
#    each value is loaded, perform property substitutions on variables
#    in the data strings with "<name>".  If a property name is not
#    available to replace a given "<name>", the literal string is left
#    in the data string unaltered.
#
###########################################################################

load_data () {
   file=$1
   section=$2

   exec 9<&0 < "$file"

   found=0
   while read line ; do
      line=`set -f ; $echo $line | tr -d '\15\32'`

      if [ $found = 0 ] ; then
         if [ "$line" = "[$section]" ] ; then
            found=1
         fi
      elif [ "`set -f ; $echo $line | sed -n '/^\[..*\]$/ {p;}'`" ] ; then
         break
      elif [ "`set -f ; $echo $line | sed -n '/^[ \t\v\f]*[A-Za-z0-9_][A-Za-z0-9_]*[ \t\v\f]*=.*$/ {p;}'`" ] ; then
         property=`set -f ; $echo $line | sed 's/^[ \t\v\f]*\([A-Za-z0-9_][A-Za-z0-9_]*\)[ \t\v\f]*=\(.*\)$/\1="\2"/'`
         property=`set -f ; $echo $property | sed 's/\(<\([A-Za-z0-9_][A-Za-z0-9_]*\)>\)/${PROPERTY_\2-\1}/g'`
         eval $property
      fi
   done 

   exec 0<&9 9<&-
}

###########################################################################
#
#  load_properties
#    Load all of the properties in the given section of a given file.
#
###########################################################################

load_properties () {
   file=$1
   section=$2

   exec 9<&0 < "$file"

   found=0
   while read line ; do
      line=`set -f ; $echo $line | tr -d '\15\32'`

      if [ $found = 0 ] ; then
         if [ "$line" = "[$section]" ] ; then
            found=1
         fi
      elif [ "`set -f ; $echo $line | sed -n '/^\[..*\]$/ {p;}'`" ] ; then
         break
      elif [ "`set -f ; $echo $line | sed -n '/^[ \t\v\f]*[A-Za-z0-9_][A-Za-z0-9_]*[ \t\v\f]*=.*$/ {p;}'`" ] ; then
         property=`set -f ; $echo $line | sed 's/^[ \t\v\f]*\([A-Za-z0-9_][A-Za-z0-9_]*\)[ \t\v\f]*=\(.*\)$/PROPERTY_\1="\2"/'`
         eval $property
      fi
   done 

   exec 0<&9 9<&-
}

###########################################################################
#
#  set_umask
#    Set the umask according to the rules defined in the data.
#
###########################################################################

set_umask () {
   mask=`umask`

   if [ "$umask_user" ] ; then
      mask=`set -f ; echo $mask | sed "s/[0-7]\([0-7][0-7]\)$/$umask_user\1/"`
   fi

   if [ "$umask_group" ] ; then
      mask=`set -f ; echo $mask | sed "s/[0-7]\([0-7]\)$/$umask_group\1/"`
   fi

   if [ "$umask_other" ] ; then
      mask=`set -f ; echo $mask | sed "s/[0-7]$/$umask_other/"`
   fi

   umask $mask
}

###########################################################################
#
#  parse_arguments
#    Parse the command line arguments and set the necessary variables.
#
###########################################################################

parse_arguments () {
   # Parse command line arguments
   while [ "$1" != "" ] ; do
      case $1 in
         -templocation)
            shift
            if [ -d "$1" ] ; then
               templocation=$1
            fi
            shift
            continue;;
         -quiet)
            headless=1
            shift
            continue;;
         -installsas)
            headless=1
            shift
            continue;;
         *)
            shift
            continue;;
      esac
   done
}


########
# Main #
########

pwd="`pwd`"
PROPERTY_WORKINGDIR="$pwd"

exe="$0"

# Dereference any symbolic links to the real executable if there is no paired INI file
if [ ! "`locate_data_file "$exe" ".ini"`" ] ; then
   while [ -h "$exe" ]; do
      link="`ls -ld "$exe"`"
      link="`expr "$link" : '.*-> \(.*\)'`"
      if [ "`expr "$link" : '/.*'`" = 0 ]; then
         exe="`dirname "$exe"`/$link"
      else
         exe="$link"
      fi
   done
fi

# Determine the script name (less any extensions)
script="`basename "$exe" | sed 's/^\([^\.]*\).*$/\1/'`"

# Determine the startup location
cd "`dirname "$exe"`"
startuplocation="`pwd`"
PROPERTY_LAUNCHERDIR="$startuplocation"
cd "$pwd"

# Determine if we are running in console mode
if [ "`set -f ;  $echo $script | sed -n '/_console$/ {p;}'`" ] ; then
   mode="console"
fi

parse_arguments "$@"

detect_host

# Test for an INI file paired with the shell script (by script name)
inifile="`locate_data_file "$startuplocation/$script" ".ini"`"
if [ ! "$inifile" ] ; then
   $echo "Error: Missing $script.ini."
   exit 1
fi

# Determine if there is a master properties file to read first by parsing the INI
load_properties "$inifile" properties

# Parse the master properties file if it exists
if [ "$PROPERTY_MASTERPROP" ] ; then
   # The path to the master property file may be relative or absolute
   if [ ! "`set -f ; $echo $PROPERTY_MASTERPROP | sed -n '/^\// {p;}'`" ] ; then
      PROPERTY_MASTERPROP="$startuplocation/$PROPERTY_MASTERPROP"
   fi

   if [ -f "$PROPERTY_MASTERPROP" ] ; then
      load_properties "$PROPERTY_MASTERPROP" properties
   else
      $echo "Error: Missing $PROPERTY_MASTERPROP."
      exit 1
   fi
fi

# Parse the INI file properties again to override any properties from the master
load_properties "$inifile" properties

# Parse the INI file for data specific to the detected platform
load_data "$inifile" default
load_data "$inifile" "$platform"

# Test for a DISPLAY
if [ "$mode" != "console" -a ! "$headless" -a "$platform" != "mpp" -a "$platform" != "mac" -a "$platform" != "m64" -a ! "$DISPLAY" ] ; then
   $echo "Error: Your DISPLAY environmental variable has not been set."
   $echo "Please set it and run this application again."
   exit 2
fi

# Set the umask
set_umask

# Establish the applogloc if not already set
if [ ! "$applogloc" ] ; then
   timestamp="`date "+%Y-%m-%d-%H.%M.%S"`"
   applogloc="$HOME/.SASAppData/SASDeploymentWizard/${script}_${timestamp}.log"
fi

# Perform a sanity check to be sure we have enough to proceed
if [ ! "$launchercmd" ] ; then
   $echo "Error: The application cannot be run on this platform: $platform."
   exit 3
fi

if [ ! "$launcherargs" ] ; then
   # Assemble the JavaArgs
   argnum=1
   while [ "`eval $echo "$"{JavaArgs_$argnum"+0}"`" ] ; do
      value="`eval $echo "$"JavaArgs_$argnum""`"

      launcherargs="$launcherargs $value"

      argnum=`expr $argnum + 1`
   done

   # Assemble the AddtlArgs
   launcherargs="$launcherargs $Classpath $MainClass"

   # Assemble the AddtlArgs
   argnum=1
   while [ "`eval $echo "$"{AddtlArgs_$argnum"+0}"`" ] ; do
      value="`eval $echo "$"AddtlArgs_$argnum""`"

      launcherargs="$launcherargs $value"

      argnum=`expr $argnum + 1`
   done
fi

if [ "$mode" != "console" ] ; then
   # Set up the logging directory and initialize the log
   mkdir -p "`dirname "$applogloc"`" 1> /dev/null 2>&1

   $echo "---------------------------------------------------------------" >> "$applogloc"
   date >> "$applogloc"
fi

# Change to the startup location
if [ ! "${startdir+0}" ] ; then
   cd "$PROPERTY_LAUNCHERDIR"
elif [ "$startdir" ] ; then
   cd "$startdir"
fi

# If he launchercmd has multiple paths separated by colons, find the first one that works
lc=`echo "$launchercmd" | 
   awk -F: '{for (i = 1; i <= NF; i++) printf "%s\n", $i}' | 
   while read line ; do 
      if [ -x "$line" ] ; then
         echo "$line"
         break;
      fi
   done`
if [ "$lc" != "" ] ; then
   launchercmd="$lc"
else
   $echo "Error: The application cannot be run on this platform: $platform."
   exit 3
fi


# Run the command
if [ "$mode" = "console" ] ; then
   "$launchercmd" $launcherargs "$@"
else
   "$launchercmd" $launcherargs "$@" 1>> "$applogloc" 2>&1
fi

rc=$?

# Return to the original directory
cd "$pwd"

# Do cleanup as necessary
if [ "$templocation" ] ; then
   rm -rf "$templocation" 1> /dev/null 2>&1
fi

exit $rc
