#!/bin/bash
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

if [ "${TESTPATCHDEBUG}" == "true" ] ; then
    set -x
fi

BASEDIR=$(pwd)
TASKNAME="COMPILE"
OP=""
TEMPDIR=""
REPORTDIR=""
SUMMARYFILE=""
STDOUT="/dev/null"
MVNPASSTHRU=""

###############################################################################
cleanupAndExit() {
    exit $1
}
###############################################################################
printUsage() {
    echo "Usage: $0 --taskname | (--op=pre|post|report --tempdir=<TEMP DIR> --reportdir=<REPORT DIR> --summaryfile=<SUMMARY FILE>) [--verbose] [-D<VALUE>...] [-P<VALUE>...]"
    echo
}
###############################################################################
parseArgs() {
    for i in $*
    do
        case $i in
        --taskname)
            echo ${TASKNAME}
            exit 0
            ;;
        --op=*)
            OP=${i#*=}
            ;;
        --tempdir=*)
            TEMPDIR=${i#*=}
            ;;
        --reportdir=*)
            REPORTDIR=${i#*=}
            ;;
        --summaryfile=*)
            SUMMARYFILE=${i#*=}
            ;;
        --verbose)
            STDOUT="/dev/stdout"
            ;;
        -D*)
            MVNPASSTHRU="${MVNPASSTHRU} $i"
            ;;
        -P*)
            MVNPASSTHRU="${MVNPASSTHRU} $i"
            ;;
        esac
    done
    if [[ "${TASKNAME}" == "" || "${OP}" == "" || "${TEMPDIR}" == "" || "${REPORTDIR}" == "" || "${SUMMARYFILE}" == "" ]] ; then
        echo "Missing options"
        echo
        printUsage
        cleanupAndExit 1
    fi
    if [[ "${OP}" != "pre" && "${OP}" != "post" && "${OP}" != "report" ]] ; then
        echo "Invalid operation"
        echo
        printUsage
        cleanupAndExit 1
    fi
}
###############################################################################
checkForWarnings() {
    grep '\[WARNING\]' ${REPORTDIR}/${TASKNAME}-clean.txt > ${TEMPDIR}/${TASKNAME}-javacwarns-clean.txt
    grep '\[WARNING\]' ${REPORTDIR}/${TASKNAME}-patch.txt > ${TEMPDIR}/${TASKNAME}-javacwarns-patch.txt
    cleanWarns=`cat ${TEMPDIR}/${TASKNAME}-javacwarns-clean.txt | awk 'BEGIN {total = 0} {total += 1} END {print total}'`
    patchWarns=`cat ${TEMPDIR}/${TASKNAME}-javacwarns-patch.txt | awk 'BEGIN {total = 0} {total += 1} END {print total}'`
    newWarns=`expr $patchWarns - $cleanWarns`
    if [[ $newWarns -le 0 ]] ; then
        REPORT+=("{color:green}+1{color} the patch does not seem to introduce new javac warnings")
        newWarns=0
    else
        REPORT+=("{color:red}-1{color} the patch seems to introduce $newWarns new javac warning(s)")
        newWarns=1
    fi
    if [[ $cleanWarns != 0 ]] ; then
        REPORT+=("{color:red}WARNING{color}: the current HEAD has $cleanWarns javac warning(s)")
    fi
}
###############################################################################


parseArgs "$@"

case $OP in
pre)
    mvn clean install -DskipTests ${MVNPASSTHRU} | tee ${REPORTDIR}/${TASKNAME}-clean.txt >> $STDOUT
    if [[ ${PIPESTATUS[0]} == 0 ]] ; then
        echo "{color:green}+1{color} HEAD compiles" >> ${TEMPDIR}/${TASKNAME}-compile.txt
    else
        echo "{color:red}-1{color} HEAD does not compile" >> ${TEMPDIR}/${TASKNAME}-compile.txt
    fi
    ;;
post)
    mvn clean install -DskipTests ${MVNPASSTHRU} | tee ${REPORTDIR}/${TASKNAME}-patch.txt >> $STDOUT
    if [[ ${PIPESTATUS[0]} == 0 ]] ; then
        echo "{color:green}+1{color} patch compiles" >> ${TEMPDIR}/${TASKNAME}-compile.txt
    else
        echo "{color:red}-1{color} patch does not compile" >> ${TEMPDIR}/${TASKNAME}-compile.txt
    fi
    ;;
report)
    REPORT=()
    compileErrors=0
    while read line; do
        REPORT+=("$line")
        if [[ "$line" =~ "-1" ]] ; then
            compileErrors=1
        fi
    done < ${TEMPDIR}/${TASKNAME}-compile.txt
    checkForWarnings
    total=`expr $compileErrors + $newWarns`
    if [[ $total == 0 ]] ; then
        echo "{color:green}+1 ${TASKNAME}{color}" >> $SUMMARYFILE
    else
        echo "{color:red}-1 ${TASKNAME}{color}" >> $SUMMARYFILE
    fi
    for line in "${REPORT[@]}" ; do
        echo ".    ${line}" >> $SUMMARYFILE
    done
    ;;
esac

exit 0
