#!/bin/sh

# Turn on/off debugging and info.  Info speaks only when a jre is found:
DEBUG=0
INFO=1

#-- MVPJAVALINK="/usr/mvp_java"

while getopts tl: arg
do   
	case $arg in
		t) DEBUG="1"
			;;
		l) MVPJAVALINK="${OPTARG}"
			;;
      *) echo "`basename $0` [-l link] [-t]"
			exit
			;;
	esac
done

#-- Web Deployment --#
if [ -z "${MVPJAVALINK}" ];then
	FDIR=`dirname $0`
	cd ${FDIR}
	pwd | egrep ".markvision/bin$" >/dev/null 2>&1
	if [ $? -eq 0 ];then
		cd ..
		MVPJAVALINK="`pwd`/jre"
	else
		echo "`basename $0` [-l link] [-t]"
		exit
	fi
fi
		
# Locations of awk and sed:
if [ -x "/bin/awk" ];then      AWK="/bin/awk"           ; else AWK="/usr/bin/awk"           ; fi
if [ -x "/bin/sed" ];then      SED="/bin/sed"           ; else SED="/usr/bin/sed"           ; fi
if [ -x "/bin/expr" ];then     EXPR="/bin/expr"         ; else EXPR="/usr/bin/expr"         ; fi
if [ -x "/bin/basename" ];then BASENAME="/bin/basename" ; else BASENAME="/usr/bin/basename" ; fi

# Default Directories to search in (case-sensitive).  DO NOT include trailing slash (/):
DEFDIRS="/usr/local /opt /usr/lpp /usr/lib /usr /usr/???print ${HOME}"

# Possible strings by which the java directory will be named (case-insensitive):
DIRSTRINGS="java jdk jre j2re j2sdk"

# Directories possibly containing the java executable (case-sensitive).  DO NOT include trailing slash (/):
JAVABINDIRS="bin jre/bin"

# Check if MVP Java link is valid before doing any other searches:
CHECKMVPJAVALINKFIRST="1"

# Exit after finding first adequate JRE (Takes MVP Java link, above, into consideration):
# If this is set to 0, the best (Highest, but within JAVA_MAX below) JRE found will be used.
EXITAFTERFIRSTSUCCESS="0"

# Create MVP Java link if non-existent or broken:
CREATEMVPJAVALINK="1"

debug_print () {
	if [ "${DEBUG}" = "1" ]; then printf "${1}"; fi
}

show_sep () {
	debug_print "#--------------------------------------------------------------\n"
}

info_print () {
	if [ "${INFO}" = "1" -o "${DEBUG}" = "1" ]; then printf "${1}\n"; fi
}

set_java_requirements () {
	# Specify the minimum and maximum acceptable java versions:
	debug_print "\n#--------------------------------------------------------------\n"
	JAVA_MIN="1.5.0"
	JAVA_MAX="1.6.0"
	debug_print " JAVA_MIN = ${JAVA_MIN}\n JAVA_MAX = ${JAVA_MAX}\n"

	# Reckon the sub versions:
	JAVA_MIN_MAJOR=`echo ${JAVA_MIN} | ${AWK} -F. '{ print $1 }'`
	JAVA_MIN_MINOR=`echo ${JAVA_MIN} | ${AWK} -F. '{ print $2 }'`
	JAVA_MIN_SUBMINOR=`echo ${JAVA_MIN} | ${AWK} -F. '{ print $3 }'`
	debug_print " JAVA_MIN_MAJOR = ${JAVA_MIN_MAJOR}, JAVA_MIN_MINOR = ${JAVA_MIN_MINOR}, JAVA_MIN_SUBMINOR = ${JAVA_MIN_SUBMINOR}\n"

	JAVA_MAX_MAJOR=`echo ${JAVA_MAX} | ${AWK} -F. '{ print $1 }'`
	JAVA_MAX_MINOR=`echo ${JAVA_MAX} | ${AWK} -F. '{ print $2 }'`
	JAVA_MAX_SUBMINOR=`echo ${JAVA_MAX} | ${AWK} -F. '{ print $3 }'`
	debug_print " JAVA_MAX_MAJOR = ${JAVA_MAX_MAJOR}, JAVA_MAX_MINOR = ${JAVA_MAX_MINOR}, JAVA_MAX_SUBMINOR = ${JAVA_MAX_SUBMINOR}\n"
	debug_print "#--------------------------------------------------------------\n"
}

already_found () {
	# Check to make sure that we haven't already found this path:
	for a in `echo ${JRES} | ${SED} 's/\:/\ /g'`; do
		if [ "${a}" = "\"$1\"" ]; then
			return 1
		fi
	done
}

check_java_version () {
	#-- Check the version of the java executable passed in.  Return 0 if acceptable, 1 otherwise:
	info_print "\n Checking  : ${1}"
	VERSION_FULL=`${1} -version 2>&1`
	VERSION=`printf "${VERSION_FULL}\n" | ${SED} 1q`
	info_print " Version   : ${VERSION}"

	if [ "`uname`" = "Linux" ];then
		printf "${VERSION_FULL}\n" | grep -i ibm >/dev/null 2>&1
		if [ $? -eq 0 ];then
			info_print " IBM Java Runtime Environment is not currently supported."
			return 1
		fi
	fi
			
	ARG1=`echo ${VERSION} | ${AWK} '{ print $1 }'`
	ARG2=`echo ${VERSION} | ${AWK} '{ print $2 }'`
	VER3=`echo ${VERSION} | ${AWK} '{ print $3 }'`

	if [ "${ARG1}" = "java" -a "${ARG2}" = "version" ]; then
		FULLVER=`echo ${VER3} | $SED 's/\"//g'`
		# Compare Major, minor and sub-minor versions:
		if [ "${FULLVER}" != "" ]; then
			VERMAJOR=`echo ${FULLVER} | ${AWK} -F. '{ print $1 }'`
			VERMINOR=`echo ${FULLVER} | ${AWK} -F. '{ print $2 }'`
			#-- In some instances, VERSUBMINOR will end up with a underscore and another subversion.
			VERSUBMINOR=`echo $FULLVER | $AWK -F. '{ print $3 }' | $SED 's/_.*$//'`
			if [ ${VERMAJOR} -lt ${JAVA_MIN_MAJOR} ]; then
				info_print " Java Runtime Environment ${FULLVER} is too old (Min JRE = ${JAVA_MIN})"
				return 1
			elif [ ${VERMAJOR} -gt ${JAVA_MAX_MAJOR} ]; then
				info_print " Java Runtime Environment ${FULLVER} is too new (Max JRE = ${JAVA_MAX})"
				return 1
			else
				if [ ${VERMINOR} -lt ${JAVA_MIN_MINOR} ]; then
					info_print " Java Runtime Environment ${FULLVER} is too old (Min JRE = ${JAVA_MIN})"
					return 1
				elif [ ${VERMINOR} -gt ${JAVA_MAX_MINOR} ]; then
					info_print " Java Runtime Environment ${FULLVER} is too new (Max JRE = ${JAVA_MAX})"
					return 1
				else
					if [ ${VERSUBMINOR} -lt ${JAVA_MIN_SUBMINOR} ]; then
						info_print " Java Runtime Environment ${FULLVER} is too old (Min JRE = ${JAVA_MIN})"
						return 1
					elif [ ${VERSUBMINOR} -gt ${JAVA_MAX_SUBMINOR} ]; then
						info_print " Java Runtime Environment ${FULLVER} is too new (Max JRE = ${JAVA_MAX})"
						return 1
					else
						info_print " Java Runtime Environment ${FULLVER} appears to be an acceptable version."
						# An 'array' of colon-delimited valid jre paths:
						if [ ! -z "${JRES}" ]; then
							# Keep track of best JRE candidate if not picking first one:
							if [ "${EXITAFTERFIRSTSUCCESS}" != "1" ]; then
								for c in `echo ${VERS} | sed 's/\:/\ /g'`; do
									if [ `${EXPR} "${FULLVER}" \> "${c}"` ]; then
										BEST_JRE="\"${1}\""
										BEST_VER="\"${FULLVER}\""
									fi
								done
							fi
							JRES="${JRES}:\"${1}\""
							VERS="${VERS}:\"${FULLVER}\""
						else
							# Keep track of best JRE candidate if not picking first one:
							BEST_JRE="\"${1}\""
							BEST_VER="\"${FULLVER}\""
							JRES="\"${1}\""
							VERS="\"${FULLVER}\""
						fi
						if [ "${EXITAFTERFIRSTSUCCESS}" = "1" ]; then
							on_exit
						else
							return 0
						fi
					fi
				fi
			fi
		else
			info_print " Invalid Java Version: Empty version string encountered"
			return 1
		fi
	else
		# Unacceptable version string format -- unable to ascertain version:
		info_print " Invalid Java Version: Unacceptable version string format encountered"
		return 1
	fi
}

check_java_bin_dir () {
	# Look for possible Java binary (bin) subdirectories in the path passed in.
	FOUND_VALID=0
	for x in `echo ${JAVABINDIRS}`
	do
		if [ -d "${1}/${x}" ]; then
			debug_print "\n\n FILE      : ${1}/${x}/java "
			if [ -x "${1}/${x}/java" -a ! -d "${1}/${x}/java" ]; then
				already_found "${1}/${x}/java"
				if [ ${?} != 1 ]; then
					# Check if appropriate libraries exist in ../lib:
					if [ -f "${1}/${x}/../lib/fontconfig.properties.src" -o -f "${1}/${x}/../lib/fontconfig.properties" ]; then
						debug_print ": FOUND!\n"
						check_java_version "${1}/${x}/java"
						if [ ${?} = 0 ]; then
							FOUND_VALID=1
						fi
					else
						debug_print ": INVALID - (${1}/${x}/../lib/fontconfig.properties) NOT FOUND!\n"
					fi
				else
					debug_print ": Already found ${1}/${x}/java, skipping...\n"
				fi
			else
				debug_print ": NOT FOUND\n"
			fi
		fi
	done
	if [ $FOUND_VALID = 1 ]; then
		return 0
	else
		return 1
	fi
}

ask_which_java()
{
	VALID_INPUT=0
	info_print "A valid Java runtime could not be found.  (Min JRE = ${JAVA_MIN}, Max JRE = ${JAVA_MAX})"
	while [ "${VALID_INPUT}" = "0" ]; do
		info_print "\nPlease enter the full path to a valid Java runtime or type 'exit' to quit: "
		read USER_JRE_INPUT
		if [ "${USER_JRE_INPUT}" = "exit" ]; then
			exit 1
		else if [ "${USER_JRE_INPUT}" != "" ]; then
			if [ ! -r "${USER_JRE_INPUT}" ];then
				info_print "\"${USER_JRE_INPUT}\" does not exist."
				continue
			fi
			if [ -d "${USER_JRE_INPUT}" ];then
				info_print "\"${USER_JRE_INPUT}\" is directory."
				continue
			fi
				
			if [ -x "${USER_JRE_INPUT}" -a ! -d "${USER_JRE_INPUT}" ]; then
				BNAME="`${BASENAME} ${USER_JRE_INPUT}`"
				DNAME="`dirname ${USER_JRE_INPUT}`"
				if [ "${BNAME}" = "java" ]; then
					if [ -f "${DNAME}/../lib/fontconfig.properties.src" -o -f "${DNAME}/../lib/fontconfig.properties" ]; then
						check_java_version "${USER_JRE_INPUT}"
						if [ "${?}" = "0" ]; then
							VALID_INPUT=1
						fi
					else
						if [ -f "${DNAME}/../jre/bin/java" ];then 
							if [ -f "${DNAME}/../jre/lib/fontconfig.properties.src" -o -f "${DNAME}/../jre/lib/fontconfig.properties" ]; then
								USER_JRE_INPUT="${DNAME}/../jre/bin/java"
								check_java_version "${USER_JRE_INPUT}"
								if [ "${?}" = "0" ]; then
									VALID_INPUT=1
								fi
							else
								info_print "\"${USER_JRE_INPUT}\" does not include lib files."
							fi
						else
							info_print "\"${USER_JRE_INPUT}\" does not exist."
						fi
					fi
				else
					info_print "\"${USER_JRE_INPUT}\" is not a java executable."
				fi
			else
				info_print "\"${USER_JRE_INPUT}\" is not an executable file."
				info_print ""
			fi
		fi
		fi
	done
}

which_java() {
	JAVA_ANSWER="no"
	COUNT=1
	info_print " Valid Java runtimes found:"
	for i in `echo ${JRES} | ${SED} 's/\:/\ /g'`
	do
		info_print " ${COUNT}. ${i}"
		eval JVM_${COUNT}="${i}"
		COUNT=`expr $COUNT + 1`
	done
	JAVA_NUM=${COUNT}

	echo " ${COUNT}. Specify a Java VM"
	COUNT=`expr $COUNT + 1`
	echo " ${COUNT}. Exit."

	while [ "${JAVA_ANSWER}" = "no" ]
	do
		printf "\n Enter your choice : [${COUNT}] "
		read answer

		#-- Check for blank or default value
		echo "${answer}" | egrep "  *" >/dev/null 2>&1
		if [ "${?}" = "0" ] || [ -z "${answer}" ];then
			answer=${COUNT}
		fi
		#-- Make sure answer is a number.
		echo "${answer}" | egrep "^[0-9][0-9]*$" >/dev/null 2>&1
		if [ "${?}" != "0" ];then
			printf "Invalid Selection! "
			continue
		fi

		#-- Make sure answer is a valid option.
		if [ ${answer} -lt 0 -o ${answer} -gt ${COUNT} ];then
			printf "Invalid Selection! "
			continue
		else
			if   [ ${answer} -eq ${COUNT} ];then
				#-- Selected None
				exit
			elif [ ${answer} -ne ${JAVA_NUM} ]; then
				eval BEST_JRE=$`echo JVM_${answer}`
				JAVA_ANSWER="yes"
			else
				ask_which_java
				JAVA_ANSWER="yes"
			fi
		fi
	done
}

on_exit () {
	# Things to do before exiting.  Output results of searches, prompt for a Java
	# runtime if none could be found and set the MVP Java link:
	info_print ""
	if [ ! -z "${JRES}" ]; then
		if [ "${EXITAFTERFIRSTSUCCESS}" = "1" ]; then
			info_print " Valid Java runtime found:"
			for i in `echo ${JRES} | ${SED} 's/\:/\ /g'`; do
				info_print " ${i}"
			done
		else
			which_java
		fi
	else
		ask_which_java
	fi
	# Create MVP Java link if it doesn't already exist:
	if [ ! -h "${MVPJAVALINK}" ]; then
		if [ "${CREATEMVPJAVALINK}" = "1" ]; then
			# Remove the double-quotes and bin/java from the JRE path:
			DEST_JRE=`echo ${BEST_JRE} | ${SED} -e 's/\"//g' -e 's/bin\/java$//'`
			info_print ""
			info_print " Creating MVP Java Link (${MVPJAVALINK} -> ${DEST_JRE})"
			ln -s "${DEST_JRE}" "${MVPJAVALINK}"
			if [ "${?}" != "0" ]; then
				info_print ""
				info_print "Error creating MVP Java Link (${MVPJAVALINK})."
				info_print "Please ensure that you have appropriate permissions to create this file."
				exit 1
			fi
		fi
	fi
	exit
}

check_mvp_java_link () {
	#-- Check if a valid MVP Java link exists before performing any other searches:
	if [ "${CHECKMVPJAVALINKFIRST}" != "1" ];then
		debug_print " CHECK MVP LINK IS DISABLED.\n"
		show_sep
		return
	fi
	if [ -h "${MVPJAVALINK}" ]; then
		debug_print " CHECK MVP LINK\n"
		info_print " Checking MVP Java Link (${MVPJAVALINK})"
		check_java_bin_dir "${MVPJAVALINK}"
		if [ "${?}" = "1" ]; then
			# Remove the link if invalid:
			info_print " Removing invalid MVP Java Link (${MVPJAVALINK})"
			rm "${MVPJAVALINK}"
			if [ "${?}" != "0" ]; then
				info_print ""
				info_print "Error removing MVP Java Link (${MVPJAVALINK})."
				info_print "Please ensure that you have appropriate permissions to remove this file."
				exit 1
			fi
		fi
	else
		debug_print " CHECK MVP LINK, LINK DOES NOT EXIST (${MVPJAVALINK}).\n"
	fi
	show_sep
}

check_env () {
	# Check for java in JAVA_HOME var:
	debug_print " CHECK USER ENVIRONMENT\n"
	if [ ! -z "${JAVA_HOME}" ]; then
		debug_print " CHECK JAVA_HOME (${JAVA_HOME})\n"
		check_java_bin_dir "${JAVA_HOME}"
	else
		debug_print " CHECK JAVA_HOME, VARIABLE DOES NOT EXIST, SKIP\n"
	fi
	# Check for java in PATH var:
	if [ $PATH ]; then
		# Split path and check for a java in each dir:
		SPLIT_PATH=`echo $PATH | $SED 's/\:/\"\ \"/g'`
		#debug_print "SPLIT_PATH = $SPLIT_PATH\n"
		for b in `echo $SPLIT_PATH`; do		
			b=`echo ${b} | sed -e 's/\"//g' -e 's!/bin$!!g' `
			check_java_bin_dir "$b"
		done
	fi
}

#
# Execution begins here:
#

set_java_requirements
check_mvp_java_link
check_env
for i in `echo ${DEFDIRS}`
do
	if [ -d "${i}" ]; then
		debug_print "Searching ${i} ...\n"
		for j in $DIRSTRINGS; do
			for k in `ls $i | grep -i $j`; do
				if [ -d "$i/$k" ]; then
					debug_print "Searching $i/$k ...\n"
					for l in $DIRSTRINGS; do
						for m in `ls $i/$k | grep -i $l`; do
							if [ -d "$i/$k/$m" ]; then
								debug_print "Searching $i/$k/$m ...\n"
								check_java_bin_dir "$i/$k/$m"
							fi
						done
					done
					check_java_bin_dir "$i/$k"
				fi
			done
		done
	fi	
done
on_exit
