#!/bin/sh

# Uncomment the following line to override the JVM search sequence
# INSTALL4J_JAVA_HOME_OVERRIDE=
# Uncomment the following line to add additional VM parameters
# INSTALL4J_ADD_VM_PARAMS=

INSTALL4J_JAVA_PREFIX=""
GREP_OPTIONS=""

fill_version_numbers() {
  if [ "$ver_major" = "" ]; then
    ver_major=0
  fi
  if [ "$ver_minor" = "" ]; then
    ver_minor=0
  fi
  if [ "$ver_micro" = "" ]; then
    ver_micro=0
  fi
  if [ "$ver_patch" = "" ]; then
    ver_patch=0
  fi
}

read_db_entry() {
  if [ -n "$INSTALL4J_NO_DB" ]; then
    return 1
  fi
  if [ ! -f "$db_file" ]; then
    return 1
  fi
  if [ ! -x "$java_exc" ]; then
    return 1
  fi
  found=1
  exec 7< $db_file
  while read r_type r_dir r_ver_major r_ver_minor r_ver_micro r_ver_patch r_ver_vendor<&7; do
    if [ "$r_type" = "JRE_VERSION" ]; then
      if [ "$r_dir" = "$test_dir" ]; then
        ver_major=$r_ver_major
        ver_minor=$r_ver_minor
        ver_micro=$r_ver_micro
        ver_patch=$r_ver_patch
        fill_version_numbers
      fi
    elif [ "$r_type" = "JRE_INFO" ]; then
      if [ "$r_dir" = "$test_dir" ]; then
        is_openjdk=$r_ver_major
        if [ "W$r_ver_minor" = "W$modification_date" ]; then
          found=0
          break
        fi
      fi
    fi
  done
  exec 7<&-

  return $found
}

create_db_entry() {
  tested_jvm=true
  version_output=`"$bin_dir/java" $1 -version 2>&1`
  is_gcj=`expr "$version_output" : '.*gcj'`
  is_openjdk=`expr "$version_output" : '.*openjdk'`
  if [ "$is_gcj" = "0" ]; then
    java_version=`expr "$version_output" : '.*"\(.*\)".*'`
    ver_major=`expr "$java_version" : '\([0-9][0-9]*\).*'`
    ver_minor=`expr "$java_version" : '[0-9][0-9]*\.\([0-9][0-9]*\).*'`
    ver_micro=`expr "$java_version" : '[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*'`
    ver_patch=`expr "$java_version" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*[\._]\([0-9][0-9]*\).*'`
  fi
  fill_version_numbers
  if [ -n "$INSTALL4J_NO_DB" ]; then
    return
  fi
  db_new_file=${db_file}_new
  if [ -f "$db_file" ]; then
    awk '$2 != "'"$test_dir"'" {print $0}' $db_file > $db_new_file
    rm "$db_file"
    mv "$db_new_file" "$db_file"
  fi
  dir_escaped=`echo "$test_dir" | sed -e 's/ /\\\\ /g'`
  echo "JRE_VERSION	$dir_escaped	$ver_major	$ver_minor	$ver_micro	$ver_patch" >> $db_file
  echo "JRE_INFO	$dir_escaped	$is_openjdk	$modification_date" >> $db_file
  chmod g+w $db_file
}

check_date_output() {
  if [ -n "$date_output" -a $date_output -eq $date_output 2> /dev/null ]; then
    modification_date=$date_output
  fi
}

test_jvm() {
  tested_jvm=na
  test_dir=$1
  bin_dir=$test_dir/bin
  java_exc=$bin_dir/java
  if [ -z "$test_dir" ] || [ ! -d "$bin_dir" ] || [ ! -f "$java_exc" ] || [ ! -x "$java_exc" ]; then
    return
  fi

  modification_date=0
  date_output=`date -r "$java_exc" "+%s" 2>/dev/null`
  if [ $? -eq 0 ]; then
    check_date_output
  fi
  if [ $modification_date -eq 0 ]; then
    stat_path=`command -v stat 2> /dev/null`
    if [ "$?" -ne "0" ] || [ "W$stat_path" = "W" ]; then
      stat_path=`which stat 2> /dev/null`
      if [ "$?" -ne "0" ]; then
        stat_path=""
      fi
    fi
    if [ -f "$stat_path" ]; then
      date_output=`stat -f "%m" "$java_exc" 2>/dev/null`
      if [ $? -eq 0 ]; then
        check_date_output
      fi
      if [ $modification_date -eq 0 ]; then
        date_output=`stat -c "%Y" "$java_exc" 2>/dev/null`
        if [ $? -eq 0 ]; then
          check_date_output
        fi
      fi
    fi
  fi

  tested_jvm=false
  read_db_entry || create_db_entry $2

  if [ "$ver_major" = "" ]; then
    return;
  fi
  if [ "$ver_major" -lt "11" ]; then
    return;
  elif [ "$ver_major" -eq "11" ]; then
    if [ "$ver_minor" -lt "0" ]; then
      return;
    fi
  fi

  if [ "$ver_major" = "" ]; then
    return;
  fi
  if [ "$ver_major" -gt "12" ]; then
    return;
  fi

  app_java_home=$test_dir
}

add_class_path() {
  if [ -n "$1" ] && [ `expr "$1" : '.*\*'` -eq "0" ]; then
    local_classpath="$local_classpath${local_classpath:+:}${1}${2}"
  fi
}

add_module_path() {
  if [ -n "$1" ] && [ `expr "$1" : '.*\*'` -eq "0" ]; then
    local_modulepath="$local_modulepath${local_modulepath:+:}${1}${2}"
  fi
}


read_vmoptions() {
  vmoptions_file=`eval echo "$1" 2>/dev/null`
  if [ ! -r "$vmoptions_file" ]; then
    vmoptions_file="$prg_dir/$vmoptions_file"
  fi
  if [ -r "$vmoptions_file" ] && [ -f "$vmoptions_file" ]; then
    exec 8< "$vmoptions_file"
    while read cur_option<&8; do
      is_comment=`expr "W$cur_option" : 'W *#.*'`
      if [ "$is_comment" = "0" ]; then 
        vmo_classpath=`expr "W$cur_option" : 'W *-classpath \(.*\)'`
        vmo_classpath_a=`expr "W$cur_option" : 'W *-classpath/a \(.*\)'`
        vmo_classpath_p=`expr "W$cur_option" : 'W *-classpath/p \(.*\)'`
        vmo_include=`expr "W$cur_option" : 'W *-include-options \(.*\)'`
        if [ ! "W$vmo_include" = "W" ]; then
            if [ "W$vmo_include_1" = "W" ]; then
              vmo_include_1="$vmo_include"
            elif [ "W$vmo_include_2" = "W" ]; then
              vmo_include_2="$vmo_include"
            elif [ "W$vmo_include_3" = "W" ]; then
              vmo_include_3="$vmo_include"
            fi
        fi
        if [ ! "$vmo_classpath" = "" ]; then
          local_classpath="$i4j_classpath:$vmo_classpath"
        elif [ ! "$vmo_classpath_a" = "" ]; then
          local_classpath="${local_classpath}:${vmo_classpath_a}"
        elif [ ! "$vmo_classpath_p" = "" ]; then
          local_classpath="${vmo_classpath_p}:${local_classpath}"
        elif [ "W$vmo_include" = "W" ]; then
          needs_quotes=`expr "W$cur_option" : 'W.* .*'`
          if [ "$needs_quotes" = "0" ]; then 
            vmoptions_val="$vmoptions_val $cur_option"
          else
            if [ "W$vmov_1" = "W" ]; then
              vmov_1="$cur_option"
            elif [ "W$vmov_2" = "W" ]; then
              vmov_2="$cur_option"
            elif [ "W$vmov_3" = "W" ]; then
              vmov_3="$cur_option"
            elif [ "W$vmov_4" = "W" ]; then
              vmov_4="$cur_option"
            elif [ "W$vmov_5" = "W" ]; then
              vmov_5="$cur_option"
            fi
          fi
        fi
      fi
    done
    exec 8<&-
    if [ ! "W$vmo_include_1" = "W" ]; then
      vmo_include="$vmo_include_1"
      unset vmo_include_1
      read_vmoptions "$vmo_include"
    fi
    if [ ! "W$vmo_include_2" = "W" ]; then
      vmo_include="$vmo_include_2"
      unset vmo_include_2
      read_vmoptions "$vmo_include"
    fi
    if [ ! "W$vmo_include_3" = "W" ]; then
      vmo_include="$vmo_include_3"
      unset vmo_include_3
      read_vmoptions "$vmo_include"
    fi
  fi
}


unpack_file() {
  if [ -f "$1" ]; then
    jar_file=`echo "$1" | awk '{ print substr($0,1,length-5) }'`
    bin/unpack200 -r "$1" "$jar_file" > /dev/null 2>&1

    if [ $? -ne 0 ]; then
      echo "Error unpacking jar files. The architecture or bitness (32/64)"
      echo "of the bundled JVM might not match your machine."
      echo "You might also need administrative privileges for this operation."
      exit 1
    else
      chmod a+r "$jar_file"
    fi
  fi
}

run_unpack200() {
  if [ -d "$1/lib" ]; then
    old_pwd200=`pwd`
    cd "$1"
    for pack_file in lib/*.jar.pack
    do
      unpack_file $pack_file
    done
    for pack_file in lib/ext/*.jar.pack
    do
      unpack_file $pack_file
    done
    cd "$old_pwd200"
  fi
}

search_jre() {
if [ -z "$app_java_home" ]; then
  test_jvm "$INSTALL4J_JAVA_HOME_OVERRIDE"
fi

if [ -z "$app_java_home" ]; then
if [ -f "$app_home/.install4j/pref_jre.cfg" ]; then
    read file_jvm_home < "$app_home/.install4j/pref_jre.cfg"
    test_jvm "$file_jvm_home"
    if [ -z "$app_java_home" ] && [ $tested_jvm = "false" ]; then
if [ -f "$db_file" ]; then
  rm "$db_file" 2> /dev/null
fi
        test_jvm "$file_jvm_home"
    fi
fi
fi

if [ -z "$app_java_home" ]; then
  test_jvm "$app_home/jre" 
  if [ -z "$app_java_home" ] && [ $tested_jvm = "false" ]; then
if [ -f "$db_file" ]; then
  rm "$db_file" 2> /dev/null
fi
    test_jvm "$app_home/jre"
  fi
fi

if [ -z "$app_java_home" ]; then
  test_jvm "$app_home/.install4j/jre.bundle/Contents/Home" 
  if [ -z "$app_java_home" ] && [ $tested_jvm = "false" ]; then
if [ -f "$db_file" ]; then
  rm "$db_file" 2> /dev/null
fi
    test_jvm "$app_home/.install4j/jre.bundle/Contents/Home"
  fi
fi

if [ -z "$app_java_home" ]; then
  test_jvm "$JAVA_HOME"
fi

if [ -z "$app_java_home" ]; then
  prg_jvm=`command -v java 2> /dev/null`
  if [ "$?" -ne "0" ] || [ "W$prg_jvm" = "W" ]; then
    prg_jvm=`which java 2> /dev/null`
    if [ "$?" -ne "0" ]; then
      prg_jvm=""
    fi
  fi
  if [ ! -z "$prg_jvm" ] && [ -f "$prg_jvm" ]; then
    old_pwd_jvm=`pwd`
    path_java_bin=`dirname "$prg_jvm"`
    cd "$path_java_bin"
    prg_jvm=java

    while [ -h "$prg_jvm" ] ; do
      ls=`ls -ld "$prg_jvm"`
      link=`expr "$ls" : '.*-> \(.*\)$'`
      if expr "$link" : '.*/.*' > /dev/null; then
        prg_jvm="$link"
      else
        prg_jvm="`dirname $prg_jvm`/$link"
      fi
    done
    path_java_bin=`dirname "$prg_jvm"`
    cd "$path_java_bin"
    cd ..
    path_java_home=`pwd`
    cd "$old_pwd_jvm"
    test_jvm "$path_java_home"
  fi
fi


if [ -z "$app_java_home" ]; then
  common_jvm_locations="/opt/i4j_jres/* /usr/local/i4j_jres/* $HOME/.i4j_jres/* /usr/bin/java* /usr/bin/jdk* /usr/bin/jre* /usr/bin/j2*re* /usr/bin/j2sdk* /usr/java* /usr/java*/jre /usr/jdk* /usr/jre* /usr/j2*re* /usr/j2sdk* /usr/java/j2*re* /usr/java/j2sdk* /opt/java* /usr/java/jdk* /usr/java/jre* /usr/lib/java/jre /usr/local/java* /usr/local/jdk* /usr/local/jre* /usr/local/j2*re* /usr/local/j2sdk* /usr/jdk/java* /usr/jdk/jdk* /usr/jdk/jre* /usr/jdk/j2*re* /usr/jdk/j2sdk* /usr/lib/jvm/* /usr/lib/java* /usr/lib/jdk* /usr/lib/jre* /usr/lib/j2*re* /usr/lib/j2sdk* /System/Library/Frameworks/JavaVM.framework/Versions/1.?/Home /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home /Library/Java/JavaVirtualMachines/*.jdk/Contents/Home/jre /Library/Java/JavaVirtualMachines/*.jre/Contents/Home /Library/Java/JavaVirtualMachines/*.jdk/Contents/Home"
  for current_location in $common_jvm_locations
  do
if [ -z "$app_java_home" ]; then
  test_jvm "$current_location"
fi

  done
fi

if [ -z "$app_java_home" ]; then
  test_jvm "$INSTALL4J_JAVA_HOME"
fi

if [ -z "$app_java_home" ]; then
if [ -f "$app_home/.install4j/inst_jre.cfg" ]; then
    read file_jvm_home < "$app_home/.install4j/inst_jre.cfg"
    test_jvm "$file_jvm_home"
    if [ -z "$app_java_home" ] && [ $tested_jvm = "false" ]; then
if [ -f "$db_file" ]; then
  rm "$db_file" 2> /dev/null
fi
        test_jvm "$file_jvm_home"
    fi
fi
fi

}

old_pwd=`pwd`

progname=`basename "$0"`
linkdir=`dirname "$0"`

cd "$linkdir"
prg="$progname"

while [ -h "$prg" ] ; do
  ls=`ls -ld "$prg"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '.*/.*' > /dev/null; then
    prg="$link"
  else
    prg="`dirname $prg`/$link"
  fi
done

prg_dir=`dirname "$prg"`
progname=`basename "$prg"`
cd "$prg_dir"
prg_dir=`pwd`
app_home=.
cd "$app_home"
app_home=`pwd`
bundled_jre_home="$app_home/jre"

if [ "__i4j_lang_restart" = "$1" ]; then
  cd "$old_pwd"
else
cd "$prg_dir"/.

fi
if [ "__i4j_extract_and_exit" = "$1" ]; then
  cd "$old_pwd"
  exit 0
fi
db_home=$HOME
db_file_suffix=
if [ ! -w "$db_home" ]; then
  db_home=/tmp
  db_file_suffix=_$USER
fi
db_file=$db_home/.install4j$db_file_suffix
if [ -d "$db_file" ] || ([ -f "$db_file" ] && [ ! -r "$db_file" ]) || ([ -f "$db_file" ] && [ ! -w "$db_file" ]); then
  db_file=$db_home/.install4j_jre$db_file_suffix
fi
if [ ! "__i4j_lang_restart" = "$1" ]; then
run_unpack200 "$bundled_jre_home"
run_unpack200 "$bundled_jre_home/jre"
fi
search_jre
if [ -z "$app_java_home" ]; then
if [ -f "$db_file" ]; then
  rm "$db_file" 2> /dev/null
fi
  search_jre
fi
if [ -z "$app_java_home" ]; then
  echo No suitable Java Virtual Machine could be found on your system.
  echo The version of the JVM must be at least 11.0 and at most 12.
  echo Please define INSTALL4J_JAVA_HOME to point to a suitable JVM.
  exit 83
fi


local_classpath=""
i4j_classpath="$app_home/.install4j/launcher9f9f67a4.jar"
add_class_path "$i4j_classpath"
local_modulepath=""
add_module_path "$app_home/.install4j/i4jruntime.jar"
add_module_path "$app_home/./framework/lib/openjfx/linux/"
  add_class_path "$app_home/." "/*"
add_class_path "$app_home/lib/boot"
add_class_path "$app_home/./framework/lib/boot/branding-3.9.1.jar"
add_class_path "$app_home/./framework/lib/boot/karaf-launcher-3.9.1.jar"
add_class_path "$app_home/./framework/lib/boot/opendmk_jmxremote_optional_jar-1.0-b01-ea.jar"
add_class_path "$app_home/./framework/lib/boot/org.apache.karaf.diagnostic.boot-4.2.8.jar"
add_class_path "$app_home/./framework/lib/boot/org.apache.karaf.jaas.boot-4.2.8.jar"
add_class_path "$app_home/./framework/lib/boot/org.apache.karaf.main-4.2.8.jar"
add_class_path "$app_home/./framework/lib/boot/org.apache.karaf.specs.activator-4.2.8.jar"
add_class_path "$app_home/./framework/lib/boot/osgi.core-6.0.0.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/istack-commons-runtime-3.0.10.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/jakarta.xml.bind-api-2.3.2.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/javax.activation-1.2.0.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/javax.annotation-api-1.3.1.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/jaxb-runtime-2.3.2.jar"
add_class_path "$app_home/./framework/lib/jdk9plus/txw2-2.3.2.jar"

vmoptions_val=""
read_vmoptions "$prg_dir/$progname.vmoptions"
INSTALL4J_ADD_VM_PARAMS="$INSTALL4J_ADD_VM_PARAMS $vmoptions_val"

for param in $@; do
  if [ `echo "W$param" | cut -c -3` = "W-J" ]; then
    INSTALL4J_ADD_VM_PARAMS="$INSTALL4J_ADD_VM_PARAMS `echo "$param" | cut -c 3-`"
  fi
done


has_space_options=false
if [ "W$vmov_1" = "W" ]; then
  vmov_1="-Di4jv=0"
else
  has_space_options=true
fi
if [ "W$vmov_2" = "W" ]; then
  vmov_2="-Di4jv=0"
else
  has_space_options=true
fi
if [ "W$vmov_3" = "W" ]; then
  vmov_3="-Di4jv=0"
else
  has_space_options=true
fi
if [ "W$vmov_4" = "W" ]; then
  vmov_4="-Di4jv=0"
else
  has_space_options=true
fi
if [ "W$vmov_5" = "W" ]; then
  vmov_5="-Di4jv=0"
else
  has_space_options=true
fi

return_code=0
if [ "$has_space_options" = "true" ]; then
$INSTALL4J_JAVA_PREFIX exec "$app_java_home/bin/java" "--add-reads=java.xml=java.logging" "--add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED" "--patch-module" "java.base=$prg_dir/framework/lib/endorsed/org.apache.karaf.specs.locator-4.2.8.jar" "--patch-module" "java.xml=$prg_dir/framework/lib/endorsed/org.apache.karaf.specs.java.xml-4.2.8.jar" "-p" "$prg_dir/framework/lib/openjfx/linux" "--add-modules" "javafx.base,javafx.swing,javafx.media,javafx.web,java.scripting,java.sql" "--add-opens" "java.base/java.security=ALL-UNNAMED" "--add-opens" "java.base/java.net=ALL-UNNAMED" "--add-opens" "java.base/java.lang=ALL-UNNAMED" "--add-opens" "java.base/java.util=ALL-UNNAMED" "--add-opens" "java.naming/javax.naming.spi=ALL-UNNAMED" "--add-opens" "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED" "--add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED" "--add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED" "-Dkaraf.instances=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/instances" "-Dkaraf.home=$prg_dir/framework" "-Dkaraf.base=$prg_dir/framework" "-Dkaraf.data=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data" "-Dkaraf.etc=$prg_dir/framework/etc" "-Dkaraf.log=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/log" "-Dkaraf.restart.jvm.supported=true" "-Djava.io.tmpdir=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/tmp" "-Djava.util.logging.config.file=$prg_dir/framework/etc/java.util.logging.properties" "-Dcytoscape.home=$prg_dir/" "-Dkaraf.startLocalConsole=false" "-Dkaraf.startRemoteShell=false" "$vmov_1" "$vmov_2" "$vmov_3" "$vmov_4" "$vmov_5" $INSTALL4J_ADD_VM_PARAMS -classpath "$local_classpath" -p "$local_modulepath" --add-modules com.install4j.runtime install4j.org.cytoscape.launcher.internal.Launcher  "$@"
return_code=$?
else
$INSTALL4J_JAVA_PREFIX exec "$app_java_home/bin/java" "--add-reads=java.xml=java.logging" "--add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED" "--patch-module" "java.base=$prg_dir/framework/lib/endorsed/org.apache.karaf.specs.locator-4.2.8.jar" "--patch-module" "java.xml=$prg_dir/framework/lib/endorsed/org.apache.karaf.specs.java.xml-4.2.8.jar" "-p" "$prg_dir/framework/lib/openjfx/linux" "--add-modules" "javafx.base,javafx.swing,javafx.media,javafx.web,java.scripting,java.sql" "--add-opens" "java.base/java.security=ALL-UNNAMED" "--add-opens" "java.base/java.net=ALL-UNNAMED" "--add-opens" "java.base/java.lang=ALL-UNNAMED" "--add-opens" "java.base/java.util=ALL-UNNAMED" "--add-opens" "java.naming/javax.naming.spi=ALL-UNNAMED" "--add-opens" "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED" "--add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED" "--add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED" "--add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED" "-Dkaraf.instances=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/instances" "-Dkaraf.home=$prg_dir/framework" "-Dkaraf.base=$prg_dir/framework" "-Dkaraf.data=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data" "-Dkaraf.etc=$prg_dir/framework/etc" "-Dkaraf.log=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/log" "-Dkaraf.restart.jvm.supported=true" "-Djava.io.tmpdir=\${installer:sys.userHome}/CytoscapeConfiguration/3/karaf_data/tmp" "-Djava.util.logging.config.file=$prg_dir/framework/etc/java.util.logging.properties" "-Dcytoscape.home=$prg_dir/" "-Dkaraf.startLocalConsole=false" "-Dkaraf.startRemoteShell=false" $INSTALL4J_ADD_VM_PARAMS -classpath "$local_classpath" -p "$local_modulepath" --add-modules com.install4j.runtime install4j.org.cytoscape.launcher.internal.Launcher  "$@"
return_code=$?
fi


exit $return_code