#!/bin/sh

## uncomment and put in the path where oj log, settings should end up
## if unset defaults to
##   JUMP_HOME (oj app folder) if writable or $HOME/.openjump (user home)
#JUMP_SETTINGS="/tmp/foobar"
JUMP_SETTINGS="$HOME/.openjump"

## uncomment and put the path to your jre here
#JAVA_HOME="/home/ed/jre1.6.0_21"
JAVA_HOME=${JAVA_HOME}

## uncomment and change your memory configuration here 
## Xms is initial size, Xmx is maximum size
## values are ##M for ## Megabytes, ##G for ## Gigabytes
#JAVA_MAXMEM="-Xmx512M"

## uncomment and change your language/country here 
## to overwrite OS default locale setting
#JAVA_LANG="-Duser.language=de -Duser.country=DE"

## uncomment and edit if you want some default OJ parameter set
## run OJ with '--help' argument to find out which are available
#JUMP_OPTS="-v DEBUG"

## set some defaults (as macosx.command uses this script, it might define other defaults)
MAIN="com.vividsolutions.jump.workbench.JUMPWorkbench"
JAVA_SAXDRIVER=${JAVA_SAXDRIVER-org.apache.xerces.parsers.SAXParser}
JAVA_LOOKANDFEEL=${JAVA_LOOKANDFEEL-javax.swing.plaf.metal.MetalLookAndFeel}

## check if $1 is a number utility function
is_number(){
  expr "$1" : '^[0-9][0-9]*$' > /dev/null 2>&1
}

## check if $1 is a decimal utility function
is_decimal(){
  expr "$1" : '^[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null 2>&1
}

## check if parameter is an absolute path
relPath(){ echo "$@" | awk '/^\//{exit 1}'; }

## end function, delays closing of terminal
end(){
  # show error for some time to prohibit window closing on X
  if [ "$ERROR" != "0" ]; then
    read -p "press Enter to finish" foobar
    exit 1
  else
    exit 0
  fi
}

extract_libs(){
  [ ! -d "$1" ] && echo Missing extraction folder && return 1
  # extract zipped files in native dir (our way to ship symlinks to desktops)
  for filepath in $(find "$1/" -name '*.tgz' -o -name '*.tar.gz')
  do
    echo "#####  filepath = '$filepath'"
    file=$(basename "$filepath")
    folder=$(dirname "$filepath")
    done=".$file.unzipped"

    # we create a marker file symbolizing previous successful extraction
    ( cd "$folder/"; [ -f "$file" ] && [ ! -f "$done" ] && tar -xvf "$file" && touch "$done" );
  done
}

postinstall(){
  [ ! -d "$1" ] && echo Missing app folder && exit 1
  # fix permissions
  find "$1" -type f -exec chmod 644 {} \; &&\
  find "$1" -type d -exec chmod 755 {} \; &&\
  find "$1" -type f \( -name \*.sh -o -name \*.command -o -name script -o -name OpenJUMP \) -print -exec chmod 755 {} \; &&\
  echo permissions fixed
  extract_libs "$1/lib/native" &&\
  echo native libs extracted
  which xdg-desktop-menu && xdg-desktop-menu forceupdate && echo reloaded desktop
}

macinstall(){
  # create app package
  echo "#####  MACINSTALL"
  cp -R -a "$1"/bin/OpenJUMP.app/Contents "$1" &&\
  awk '{sub(/..\/oj_/,"bin/oj_",$0)}1' "$1"/bin/OpenJUMP.app/Contents/Resources/script > "$1"/Contents/Resources/script &&\
  echo patched oj.app
  # do postinstall
  postinstall "$1"
}

ME="$0"
## absolutify home folder
relPath "$ME" && ME="$(pwd)/$ME"
# filter multiple // and ./ and replace ..
ME=$(echo "$ME"|awk '{gsub(/\/+/,"/",$0);gsub(/\/\.\//,"/",$0);while($0~/\/\.\.\//&&last!=$0){last=$0;gsub(/\/([\.][^\.]|[^\.][\.]|[^\.][^\.]|[^\/][^\/][^\/]+)\/\.\.\//,"/",$0);};print}')
# resolv possible link to our actual location 
while [ -L "$ME" ]; do
  MEBASE=$(dirname "$ME")
  ME=$(readlink -n "$ME")
  relPath "$ME" && ME="$MEBASE/$ME"
done
JUMP_HOME=$(dirname "$(dirname "$ME")")
echo ---JUMP_HOME---
echo $JUMP_HOME

## run postinstalls only, if requested
case "$1" in
 --post-install)
  postinstall "$JUMP_HOME" 2>&1 | tee "$JUMP_HOME"/postinstall.log
  exit
 ;;
 --mac-install) 
  macinstall "$JUMP_HOME" 2>&1 | tee "$JUMP_HOME"/macinstall.log
  exit
 ;;
esac

## cd into jump home
echo "#####  pwd = '$OLD_DIR'"
OLD_DIR=`pwd`
cd "$JUMP_HOME"
PWD_DIR=`pwd`
echo "##### cd '$JUMP_HOME', pwd = '$PWD_DIR'"

## determine where to place settings, if no path given
echo "#####  ===== JUMP_SETTINGS = '$JUMP_SETTINGS'"
[ -z "$JUMP_SETTINGS" ] && \
JUMP_SETTINGS="$JUMP_HOME"; \
if [ -d "$JUMP_SETTINGS" ]; then
  echo "#####  within -d \$JUMP_SETTINGS"
  if [ ! -w "$JUMP_SETTINGS" ]; then
    echo "#####  within ! -w \$JUMP_SETTINGS"
    # try users home dir
    JUMP_SETTINGS="$HOME/.openjump"
    # create if missing
    [ ! -e "$JUMP_SETTINGS" ] && mkdir "$JUMP_SETTINGS"
    # try to make it writable
    [ ! -w "$JUMP_SETTINGS" ] && chmod u+wX -R "$JUMP_SETTINGS"
    # check availability and issue warning in case
  fi
fi
if [ ! -d "$JUMP_SETTINGS" ] || [ ! -w "$JUMP_SETTINGS" ]; then 
  echo "Warning: Cannot access settings folder '$JUMP_SETTINGS' for writing."
fi

## search java, order is:
# 1. first in oj_home/jre
# 2. in configured java_home
# 3. in path
echo "#####  -----------------------------------------------------------"
echo "#####  SEARCH JAVA:"
if [ -f "$JUMP_HOME/jre/bin/java" ]; then
  JAVA="$JUMP_HOME/jre/bin/java"
  echo "#####  JAVA = '$JAVA'"
# is there a jre defined by env var?
elif [ -n "$JAVA_HOME" ]; then
  JAVA=$JAVA_HOME/bin/java
  echo "#####  JAVA = '$JAVA'"
# well, let's look what we've got in the path
else
  JAVA=`which java`
  echo "#####  JAVA = '$JAVA'"
fi

# java available
[ -z "$JAVA" ] && \
 echo "Couldn't find java in your PATH ($PATH). Please install java or 
add the location of java to your PATH environment variable." && ERROR=1 && end

# resolve recursive links to java binary
echo "#####  ===== Resolve recursive links to java binary: \$1 = '$1'"
relPath "$JAVA" && JAVA="$(pwd)/$JAVA"
echo "#####  awk script survived after \$1 test"
#while [ -L "${JAVA}" ]; do
#  JDIR=$(dirname "$JAVA")
#  JAVA_CANDIDATE=$(readlink -n "${JAVA}")
#  # protect against Gentoo's run-java-tool.bash wrapper
#  if [ $(basename "$JAVA") != $(basename "$JAVA_CANDIDATE") ]; then
#    break
#  fi
#  JAVA="$JAVA_CANDIDATE"
#  relPath "$JAVA" && JAVA="${JDIR}/${JAVA}"
#done
# java executable file?
[ ! -x "$JAVA" ] && \
 echo "The found java binary '$JAVA' is no executable file." && ERROR=1 && end

# java version check
JAVA_VERSIONSTRING="$("$JAVA" -version 2>&1)"
#JAVA_VERSION=$( echo $JAVA_VERSIONSTRING | awk 'BEGIN{done=0}{gsub(/["\047]+/,"")}/[a-zA-Z]+ version [0-9]+/{split($3,a,"[^0-9]"); if(match(a[2],/^[0-9]+$/)){print a[1]"."a[2]}else{print a[1]".0"}; done=1}END{if(!done)exit 1}' ) 
JAVA_VERSION=$(echo $JAVA_VERSIONSTRING | awk -F'"' '/^java version/ || /^openjdk version/{print $2}' | awk -F'.' '{print $1"."$2}')
echo "#####  JAVA_VERSION = '$JAVA_VERSION'"
JAVA_ARCH=$(echo $JAVA_VERSIONSTRING | grep -q -i 64-bit && echo x64 || echo x86)
JAVA_NEEDED="1.6"
if ! is_decimal "$JAVA_VERSION"; then
  echo "Warning! Your java version could not be detected properly. Please report this issue to the OJ developer list. The result was
---JAVA_VERSIONSTRING---
$JAVA_VERSIONSTRING
---JAVA_VERSION---
$JAVA_VERSION
---"
elif ! awk "BEGIN{if($JAVA_VERSION < $JAVA_NEEDED)exit 1}"; then
  echo "Your java version '$JAVA_VERSION' is insufficient to run OpenJUMP.
Please provide an at least a version '$JAVA_NEEDED' Java Runtime."
  ERROR=1
  end
fi

# always print java infos
echo ---JAVA---
echo "Using '$(basename "${JAVA}")' found in '$(dirname "${JAVA}")'"
"$JAVA" -version 2>&1|awk 'BEGIN{ORS=""}{print $0"; "}END{print "\n"}'

JUMP_PROFILE="$HOME/.openjump/openjump.profile"
if [ -f "$JUMP_PROFILE" ]; then
  source $JUMP_PROFILE
fi

# setup some lib paths
if [ -z "$JUMP_LIB" ]; then
  JUMP_LIB="./lib"
fi
echo "#####  JUMP_LIB = '$JUMP_LIB'"

JUMP_NATIVE_DIR="$JUMP_LIB/native"
JUMP_PLUGIN_DIR="${JUMP_PLUGIN_DIR:=$JUMP_LIB/ext}"
echo "#####  -----------------------------------------------------------"
echo "#####  JUMP_NATIVE_DIR = '$JUMP_NATIVE_DIR'"
echo "#####  JUMP_PLUGIN_DIR = '$JUMP_PLUGIN_DIR'"

JUMP_PLUGINS=./bin/default-plugins.xml
if [ -z "$JUMP_PLUGINS" ] || [ ! -f "$JUMP_PLUGINS" ]; then
  JUMP_PLUGINS="./bin/default-plugins.xml"
  if [ ! -f "$JUMP_PLUGINS" ]; then
    JUMP_PLUGINS="./scripts/default-plugins.xml"
  fi
fi
echo "#####  JUMP_PLUGINS = '$JUMP_PLUGINS'"

# include every jar/zip in lib and native dir
for libfile in "$JUMP_LIB/"*.zip "$JUMP_LIB/"*.jar "$JUMP_NATIVE_DIR/$JAVA_ARCH/"*.jar "$JUMP_NATIVE_DIR/"*.jar
do
  CLASSPATH="$libfile":"$CLASSPATH";
done
CLASSPATH=.:./bin:$CLASSPATH
export CLASSPATH;
echo "#####  CLASSPATH = '$CLASSPATH'"

## prepend jump opts
#
JUMP_OPTS="-extensions-directory $JUMP_PLUGIN_DIR $JUMP_OPTS"
echo "#####  JUMP_OPTS = '$JUMP_OPTS'"
if [ -f "$JUMP_PLUGINS" ]; then
  JUMP_OPTS="-default-plugins $JUMP_PLUGINS $JUMP_OPTS"
  echo "#####  JUMP_OPTS = '$JUMP_OPTS'"
fi

# workbench-properties.xml is used to manually load plugins (ISA uses this)
JUMP_PROPERTIES=./bin/workbench-properties.xml
if [ -n "$JUMP_PROPERTIES" ] && [ -f "$JUMP_PROPERTIES" ]; then
  JUMP_OPTS="-properties $JUMP_PROPERTIES $JUMP_OPTS"
  echo "#####  JUMP_OPTS = '$JUMP_OPTS'"
fi

# compile jre opts, respect already set ones by environment
JAVA_OPTS="$JAVA_MAXMEM $JAVA_LANG $JAVA_OPTS"
echo "#####  JAVA_OPTS = '$JAVA_OPTS'"
JAVA_OPTS="$JAVA_OPTS -Djump.home=."
echo "#####  JAVA_OPTS = '$JAVA_OPTS'"
[ -n "JAVA_SAXDRIVER"    ] && JAVA_OPTS="$JAVA_OPTS -Dorg.xml.sax.driver=$JAVA_SAXDRIVER"
[ -n "$JAVA_LOOKANDFEEL" ] && JAVA_OPTS="$JAVA_OPTS -Dswing.defaultlaf=$JAVA_LOOKANDFEEL"
# apply mac overrides
JAVA_OPTS="$JAVA_OPTS $JAVA_OPTS_OVERRIDE"
echo "#####  JAVA_OPTS = '$JAVA_OPTS'"

# java9+ needs some packages explicitly added/exported
if awk "BEGIN{if($JAVA_VERSION >= 9)exit 0;else exit 1}"; then
  JAVA_OPTS="--add-exports java.base/jdk.internal.loader=ALL-UNNAMED \
--add-exports java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED \
--add-exports java.desktop/com.sun.java.swing.plaf.motif=ALL-UNNAMED \
--add-exports java.desktop/com.sun.imageio.spi=ALL-UNNAMED \
--add-exports java.desktop/com.sun.imageio.plugins.tiff=ALL-UNNAMED \
$JAVA_OPTS"
fi
# java ee was removed from jdk in java 11
if awk "BEGIN{if( $JAVA_VERSION >= 9 && $JAVA_VERSION < 11 )exit 0;else exit 1}"; then
  JAVA_OPTS="--add-modules java.se.ee $JAVA_OPTS"
fi

# avoid a NoClassDefFoundError when JAI is used
JAVA_OPTS="-Dcom.sun.media.jai.disableMediaLib=true $JAVA_OPTS"

# in case some additional archives were placed in native dir inbetween
echo "#####  -----------------------------------------------------------"
#extract_libs "$JUMP_NATIVE_DIR"

# allow jre to find native libraries in native dir, lib/ext (backwards compatibility)
NATIVE_PATH="$JUMP_NATIVE_DIR/$JAVA_ARCH:$JUMP_NATIVE_DIR:$JUMP_PLUGIN_DIR"
# allow jre to find executable binaries located under the native folder
export PATH="$JUMP_NATIVE_DIR:$PATH"

# export (DY)LD_LIBRARY_PATH depending on platform
if [ "$(basename "$0")" = "oj_macosx.command" ]; then
  ## generate gdal & other native libs settings
  # spatialite also works if homebrew java is installed and used
  # via JAVA_HOME above e.g. /usr/local/opt/java11
  # home-brew gdal on mac mini-howto
  # 1. Install home-brew according to https://brew.sh
  # 2. Add osgeo4mac repo 'brew tap osgeo/osgeo4mac'
  # 3. Install gdal 'brew install osgeo-gdal'
  # DO NOT install default home-brew gdal, it lacks java support!
  # java bindings and uni libs are in /usr/local/lib/
  # gdal-data can be found in /usr/local/share/gdal
  export GDAL_DATA="/usr/local/share/gdal"
  echo ---GDAL_DATA---
  echo $GDAL_DATA

  NATIVE_PATH="$NATIVE_PATH:/usr/local/opt/sqlite/lib/:/usr/local/lib/"
  CLASSPATH="/usr/local/lib/gdal.jar:$CLASSPATH"

  ## add lib/native/[arch/] to lib path
  # this used to be DYLD_LIBRARY_PATH which is not working anymore
  # see https://stackoverflow.com/questions/20038789/default-java-library-path
  export JAVA_LIBRARY_PATH="$NATIVE_PATH"
  echo ---JAVA_LIBRARY_PATH---
  echo $JAVA_LIBRARY_PATH
else
  ## generate gdal & other native libs settings
  GDALPATH="$JUMP_NATIVE_DIR/gdal-linux-$JAVA_ARCH"
  # debian/ubuntu need package libgdal-java
  # it keeps java bindings in /usr/share/java
  # and jni libs in /usr/lib/jni, gdal-data in /usr/share/gdal
  # let's add those locations for convenience sake but prefer lib/native
  [ -e "$JUMP_NATIVE_DIR/gdal-linux-data" ] && \
  export GDAL_DATA="$JUMP_NATIVE_DIR/gdal-linux-data" || \
  export GDAL_DATA="/usr/share/gdal/"
  echo ---GDAL_DATA---
  echo $GDAL_DATA

  NATIVE_PATH="$GDALPATH:$GDALPATH/lib:$GDALPATH/java:$NATIVE_PATH:/usr/lib/jni"
  CLASSPATH="$GDALPATH/java/gdal.jar:/usr/share/java/gdal.jar:$CLASSPATH"

  export LD_LIBRARY_PATH="$NATIVE_PATH:$LD_LIBRARY_PATH"
  echo ---LD_LIBRARY_PATH---
  echo $LD_LIBRARY_PATH
fi

echo ---PATH---
echo $PATH

echo ---CLASSPATH---
echo $CLASSPATH

echo ---Save logs \& state to--- 
echo "$JUMP_SETTINGS/"

echo ---Detect maximum memory limit---
# use previously set or detect RAM size in bytes
#RAM_SIZE=${RAM_SIZE-$(expr "$(awk '/MemTotal/{print $2}' /proc/meminfo)" \* 1024)}
RAM_SIZE=${RAM_SIZE-$(expr "$(sysctl hw.realmem | awk '/hw.realmem:/{print $2}')" / 1024)}
echo "#####  -----------------------------------------------------------"
echo "#####  RAM_SIZE = '$RAM_SIZE'"

if [ -n "$JAVA_MAXMEM" ]; then
  echo "max. memory limit defined via JAVA_MAXMEM=$JAVA_MAXMEM"
elif ! is_number "$RAM_SIZE"; then
  echo "failed to detect system RAM size, using default max. memory limit of 512 MiB"
  JAVA_MAXMEM="-Xmx512M"
else
  # calculate 80% RAM (in bytes)
  MEM_80PCT=`expr "$RAM_SIZE" \* 80 / 100`
  # calculate RAM size minus 1GiB, for big RAM machines we protect max. 1GiB
  # e.g. for 80% of 16GiB not to waste 3.2GiB
  MEM_MINUS1GB=`expr "$RAM_SIZE" - \( 1024 \* 1024 \* 1024 \)`
  # use whatever is bigger
  if [ "$MEM_80PCT" -gt "$MEM_MINUS1GB" ]; then
    MEM_MAX="$MEM_80PCT"
  else
    MEM_MAX="$MEM_MINUS1GB"
  fi
  echo "#####  MEM_MAX = '$MEM_MAX'"

  # limit 32bit jre to 2GiB = 2147483648 bytes
  echo "#####  JAVA_ARCH = '$JAVA_ARCH'"
  if [ "$JAVA_ARCH" != "x64" ] && [ "$MEM_MAX" -gt "2147483648" ]; then
    MEM_MAX=2147483648
  fi

  MEM_MAX_MB=`expr $MEM_MAX / 1024 / 1024`
  MEM_MAX_MB=`expr $MEM_MAX / 1024`
  JAVA_MAXMEM="-Xmx${MEM_MAX_MB}M"
  echo "#####  JAVA_MAXMEM = '$JAVA_MAXMEM'"

  # output info
  echo set max. memory limit to $MEM_MAX_MB MiB
fi

# eventually try to start if no errors so far
if [ -z "$ERROR" ]; then
  echo ---Start OJ---
  # log.dir needs a trailing slash for path concatenation in log4j.xml
"$JAVA" -Djava.system.class.loader=com.vividsolutions.jump.workbench.plugin.PlugInClassLoader -cp "$CLASSPATH" -Dlog.dir="$JUMP_SETTINGS/" $JAVA_OPTS $MAIN -state "$JUMP_SETTINGS/" $JUMP_OPTS "$@"
  # result of jre call
  ERROR=$?
fi

## return to old working dir
cd "$OLD_DIR"

## run end function
end
