#!/bin/bash

function print_usage {
    cat << EOF
Usage: hjc [options] <class-name> ...
where [options] includes:
    -classpath <path>        search path for class files
    -sourcepath <path>       search path for hj source files (must includes path to class-name)
    -destdir <path>                location where to output classes
    -rt <value>				 set the targeted hj runtime to compile class for. (s = work sharing (default) | h workstealing help first | w = workstealing work first )
    -v -verbose --verbose    print verbose debugging information
    -hjVerbose				 print verbose hj related debugging information
    -h -help --help          print this message
    -version --version 	   	 print version number of the hj compiler

    Use "hjc -- -help" to get more detailed help on compiler options
EOF
    exit 1
}

CLASSNAME=
USER_CLASSPATH=
USER_SOURCEPATH=
RT=

RUNTIME_WSH="s"
RUNTIME_WST_HF="h"
RUNTIME_WST_WF="w"

function set_source_file_name() {
	FILENAME_PATH=`echo $args | sed "s/^ //g"`

	#We extract the source file name
	FILENAME=`echo ${FILENAME_PATH##*/}`
}


function set_sourcepath() {
	set_source_file_name

	#We extract the path that prepend the source file name.
	PREPEND_PATH=`echo ${FILENAME_PATH%"$FILENAME"}`

	# if any, we add it to the sourcepath
	if [ ! -z "$PREPEND_PATH" ]; then
		if [ -z "$USER_SOURCEPATH" ]; then
			USER_SOURCEPATH="${PREPEND_PATH}"
		else
			USER_SOURCEPATH="${PREPEND_PATH}:${USER_SOURCEPATH}"
		fi
	fi	
}

function set_classname() {
	set_source_file_name

	#we need to remove .hj suffix, as soot only takes the classname as parameter
	CLASSNAME=`echo $FILENAME | sed 's/.hj$//g'`
}

function check_and_set_runtime() {
	if [ -z "$RT" ]; then
		RT=${RUNTIME_WSH}
	else 
		if [ ! \( \( ${RT} == "${RUNTIME_WST_WF}" \) -o \( ${RT} == "${RUNTIME_WST_HF}" \) -o \( ${RT} == "${RUNTIME_WSH}" \) \) ]; then
			echo "ERROR: ${RT} is an invalid value for 'rt' option. Possible values are 's', 'h' or 'w'"
			exit 1
		fi	
	fi
}

[ -n "$JAVA_HOME" ] || JAVA_HOME='${env.JAVA_HOME}'

if [ -n "$JAVA_HOME" -a -e "$JAVA_HOME/bin/java" ]; then
    JAVA="$JAVA_HOME/bin/java"
elif [ -n "$JRE_HOME" -a -e "$JRE_HOME/bin/java" ]; then
    JAVA="$JRE_HOME/bin/java"
else
    echo "ERROR: JAVA_HOME ($JAVA_HOME) is not pointing to a JRE or a JDK"
    exit 1
fi

if [ -z "${HJ_HOME}" ]; then
	echo ""
	echo "ERROR: HJ_HOME environment variable must be defined and point to an HJ Distribution"
	echo ""
    exit 1
fi

SOOT_DIST_HOME=${HJ_HOME}
SOOT_DIST_LIB_DIR=${SOOT_DIST_HOME}/lib

HJC_CLASSPATH=

for jar in `ls ${SOOT_DIST_LIB_DIR}/*.jar`; do
	HJC_CLASSPATH=${HJC_CLASSPATH}:$jar
done


verbose=""
version=""
HjVERBOSE=
java_args=""
args=""
debug=""

parse=true
while [ -n "$1" ]; do
    if [ -z "$parse" ]; then
	args=$args $1
        shift
     P   continue
    fi
    case "$1" in
        -h|-help|--help) print_usage; break;;
        -v|-verbose|--verbose) verbose="1";;
        -version|--version) version="1";;
        -hjVerbose) HjVERBOSE="-hjVerbose";;
        -classpath|-cp) shift; USER_CLASSPATH="$1";;
        -sourcepath|-sp) shift; USER_SOURCEPATH="$1";;
        -destdir|-d) shift; DEST_DIR="$1";;
        -rt) shift; RT="$1";;        
        -debug) debug="1";;
        -J*) java_args="${java_args} '${1##-J}'";;
        --) parse=;;
        *) args="$args $1";;
    esac
    shift
done

if [ ! -z "$version" ]; then
	JAVA_CMD="$JAVA -Xmx512m -classpath ${HJC_CLASSPATH} soot.Main -version"
	eval ${JAVA_CMD}
	exit $?
fi

if [ -z "$args" ]; then
	print_usage;
fi 

# soot only takes the Classname as argument, however it will still try to find 
# a Classname.hj file in its path. 
# This check ensures only .hj files will be submit to soot.
hj_src_pattern=*.hj

case $args in 
  $hj_src_pattern) echo "" ;;
  *) echo "ERROR: Source file $args must have a .hj extension to be compiled"; exit 1;; 
esac

#sets USER_SOURCEPATH
set_sourcepath

#sets CLASSNAME to be compiled
set_classname

if [ ! -z "$USER_SOURCEPATH" ]; then
	SOOT_OPTIONS="${SOOT_OPTIONS} -sp .:${USER_SOURCEPATH}"
else
	SOOT_OPTIONS="${SOOT_OPTIONS} -sp ."	
fi 

if [ ! -z "$USER_CLASSPATH" ]; then
	SOOT_OPTIONS="${SOOT_OPTIONS} -cp ${USER_CLASSPATH}"
	HJC_CLASSPATH="${HJC_CLASSPATH}:${USER_CLASSPATH}"
fi 

if [ ! -z "$DEST_DIR" ]; then
	SOOT_OPTIONS="${SOOT_OPTIONS} -d ${DEST_DIR}"
fi 

check_and_set_runtime
SOOT_OPTIONS="${SOOT_OPTIONS} -rt ${RT}"

#File to compile, is filename without the .hj extension. That's how soot works...
JAVA_CMD="$JAVA -Xmx512m -classpath ${HJC_CLASSPATH} soot.Main ${SOOT_OPTIONS} -w -hj ${HjVERBOSE} -pp '$CLASSNAME'"
	
[ -n "$verbose" ] && echo ${JAVA_CMD}

eval ${JAVA_CMD}
exit $?