#!/bin/bash

## TODO: Move this into the Java GUI Makefile (in RNAstructure/java_interface)
## That way it can stay in sync better with changes to the GUI

# Enable better script error detection: -e=exit on any errors. -x=echo commands. -o pipefail=a pipeline's exit code is from the rightmost command to exit with a non-zero status
set -e -o pipefail
trap 'rc=$?; echo >&2 "ERROR at line ${LINENO} (rc: $rc)"; exit $rc' ERR
trap 'rc=$?; (($rc)) && { echo >&2 "EXITING DUE TO ERROR ($rc)"; exit $rc; } || echo Done.' EXIT

SELF_NAME=$(basename "${BASH_SOURCE[0]}") # get the name of this script.
SELF_DIR=$(dirname "${BASH_SOURCE[0]}") # get the directory of this script.

# Move to the RNAstructure main directory.
# !!! The entire script assumes we are operating from the root RNAstructure directory. !!!
cd $SELF_DIR/../../

SRC_ROOT=java_interface/src
# SRC_GUI=$SRC_ROOT/ur_rna/RNAstructureUI
# SRC_TESTER=$SRC_ROOT/ur_rna/GUITester
# SRC_UTIL=$SRC_ROOT/ur_rna/Utilities

PKG_ROOT=ur_rna
# PKG_GUI=${PKG_ROOT}.RNAstructureUI
# PKG_TESTER=${PKG_ROOT}.GUITester
# PKG_UTIL=${PKG_ROOT}.Utilities

LIB=java_interface/lib
ABBOT_LIBS=( $LIB/abbot.jar  $LIB/gnu-regexp-*.jar  $LIB/jdom-*.jar )
JAVA_CLASSPATH=${SRC_ROOT}:$(IFS=:; echo "${ABBOT_LIBS[*]}")

# Determine operating system
case "$OSTYPE" in 
	cygwin|msys) 	OS=Windows 	;;
	darwin*) 		OS=Mac 		;;
	linux*)			OS=Linux 	;;
	*)				echo >&2 "Unknown OS: $OSTYPE"; exit 1	;;
esac

#############################################################
# Define functions
#############################################################

# If running on Windows, we need to find that JDK path to locate javadoc
function locateJavdoc() {
	if [[ $OS == Windows ]]; then
	  JAVA_CLASSPATH="${JAVA_CLASSPATH//:/\;}" #replace : with ; on Windows.
	  if ! type -p javadoc &>/dev/null; then
		  if [[ ! -d $JAVA_HOME ]]; then
			JDKS=( /cygdrive/c/Program\ Files/Java/jdk*/bin )
			[[ ${#JDKS[@]} -eq 0 || ! -d ${JDKS[0]} ]] && JDKS=( /cygdrive/c/'Program Files (x86)'/Java/jdk*/bin )
			[[ ${#JDKS[@]} -eq 0 || ! -d ${JDKS[0]} ]] && echo >&2 "Cannot find JDK. Please set JAVA_HOME to point to a valid jdk folder."
			export JAVA_HOME=${JDKS[@]: -1}
		  fi
		  export PATH="$PATH:$JAVA_HOME/bin"
	  fi
	fi
}

DELETE_TAG="!SAFE_TO_DELETE!" # used to mark temporary comment files that have to be copied into the source directories.
function isTempCommentFile() { grep -q "$DELETE_TAG" "$1"; }
function cleanupTempCommentFiles() {
	for f in $(find $SRC_ROOT -name package.html); do 
		isTempCommentFile $f && rm $f
	done
}

# Copy the HTML comment files to their proper places and names so the Javadoc tool will use them.
function copyCommentFiles() {
	local file name pkg_dir outfile
	for file in manual/javadoc/comments/*.html; do 
		name=${file##*/}; name=${name%.html} # remove directory and extension
		[[ $name == [Oo]verview ]] && continue # skip overview.html (Overview.html)

		# Prepend the root package name.
	    if [[ $name == root_package ]]; then
	    	name=$PKG_ROOT # if a file is called "root_package.html" then it is the comments for the root package.
	    else
	    	name=$PKG_ROOT.$name #prepend the root package name
	    fi
		# the name now represents the full package name
	    # so dots can be replaced by slashes to get the destination directory
	    pkg_dir=${name//./\/}
	    outfile=$SRC_ROOT/$pkg_dir/package.html
		#echo  "$file ==> $outfile"
		# If the file exists, show a warning
		if [[ -f $outfile ]]; then
			echo >&2 "WARNING: Comment file already exists: $outfile" 
		else
			echo >$outfile "<!-- Do not edit this file. It is auto-generated by manual/javadoc/$SELF_NAME $DELETE_TAG -->"
			cat <$file >>$outfile
		fi
	done
}

function generatePackageList() {
	if [[ ! -f $1 ]]; then
		echo >$1 "# This file was auto-generated by javaDocScript. 
	# It can be edited manually and will NOT be overwritten.
	# To regenerate it, simply rename or delete this file."
		find java_interface/src/  -type d -printf "%P\n" | 
			perl -pe 's|/|.|g' >>$1
	fi
}

#############################################################
# Real program execution starts here.
#############################################################

function bady() {
	badx || echo "OK"
}


function badx() {
	return 41
}

badx || bady

locateJavdoc # find the location of javadoc on Windows

echo "Using JavaDoc: $(which javadoc)"
echo "JAVA_CLASSPATH: ${JAVA_CLASSPATH}"

cleanupTempCommentFiles # clean up any comments that might remain from a previous run

echo "Copying package.html comments into source directories."
copyCommentFiles # copy new comment files.

# flags for javadoc
javadocFlags=( 
	-private -encoding UTF-8 -nodeprecated 
	-overview  manual/javadoc/comments/overview.html
	-sourcepath ${SRC_ROOT} 
	-d manual/javadoc/html.tmp
	-classpath "${JAVA_CLASSPATH}"
	# add custom tag "@noinspection"
	-tag noinspection:a:"No IDE Inspections"
	#-link http://download.oracle.com/javase/6/docs/api/
)

FILE_PKG_LIST=manual/javadoc/packages.cfg
generatePackageList $FILE_PKG_LIST

#Get a list of all RNAstructure java packages to document
javadocPackages=( $(grep -Ev '^(#|;)' $FILE_PKG_LIST) )

#Delete old output
rm -f manual/javadoc/javadoc_{warnings,errors,output}.txt

#Delete any incomplete attempts
rm -rf manual/javadoc/html.tmp

echo javadoc "${javadocFlags[@]}" "${javadocPackages[@]}"

# Run the javadoc command 
# { { javadoc "${javadocFlags[@]}" "${javadocPackages[@]}"; } \
#    2> >(tee manual/javadoc/javadoc_warnings.txt >&2); } \
#    &> >(tee manual/javadoc/javadoc_output.txt) || true # prevent the script from ending if javadoc exits with an error code.
javadoc "${javadocFlags[@]}" "${javadocPackages[@]}" \
	>manual/javadoc/javadoc_output.txt \
    2>manual/javadoc/javadoc_warnings.txt \
   || true # prevent the script from ending if javadoc exits with an error code.


# Find lines that represent errors and copy them to javadoc_errors.txt
grep 'error:' manual/javadoc/javadoc_warnings.txt > manual/javadoc/javadoc_errors.txt || true

# If errors were found, show an error message.
if [[ -s manual/javadoc/javadoc_errors.txt ]]; then
	echo >&2 "JavaDoc had Errors. Operation aborted.  (see manual/javadoc/javadoc_errors.txt)"
else
	# Complete the process by moving the new documentation (in html.tmp/) to the html directory.
	# If the old html directory still exists, move it to a timestamped folder.
	if [[ -d manual/javadoc/html ]]; then 
		dt=$(date -r manual/javadoc/html/index.html '+%s')
		mv manual/javadoc/html manual/javadoc/html.old_$dt
		echo "JavaDoc completed successfully!"
	fi
	mv manual/javadoc/html.tmp manual/javadoc/html
fi

# Delete any copied comment files.
echo "Cleaning up temporary files."
cleanupTempCommentFiles
