#!/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="RAT"
OP=""
TEMPDIR=""
REPORTDIR=""
SUMMARYFILE=""
MVNPASSTHRU=""

###############################################################################
cleanupAndExit() {
  exit $1
}
###############################################################################
printUsage() {
  echo "Usage: $0 --taskname | (--op=pre|post|report --tempdir=<TEMP DIR> --reportdir=<REPORT DIR> --summaryfile=<SUMMARY FILE>) [-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#*=}
      ;;
    -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() {
  cleanWarns=`grep -c '\!?????' ${REPORTDIR}/${TASKNAME}-clean.txt`
  patchWarns=`grep -c '\!?????' ${REPORTDIR}/${TASKNAME}-patch.txt`
  newWarns=`expr $patchWarns - $cleanWarns`
  if [[ $newWarns -le 0 ]] ; then
    REPORT+=("{color:green}+1{color} the patch does not seem to introduce new RAT warnings")
    newWarns=0
  else
    REPORT+=("{color:red}-1{color} the patch seems to introduce $newWarns new RAT warning(s)")
    newWarns=1
  fi
  if [[ $cleanWarns != 0 ]] ; then
    REPORT+=("{color:red}WARNING: the current HEAD has $cleanWarns RAT warning(s), they should be addressed ASAP{color}")
  fi
}
###############################################################################


parseArgs "$@"

case $OP in
  pre)
    mvn apache-rat:check ${MVNPASSTHRU} > ${REPORTDIR}/${TASKNAME}-clean.txt
    ;;
  post)
    mvn apache-rat:check ${MVNPASSTHRU} > ${REPORTDIR}/${TASKNAME}-patch.txt
    ;;
  report)
    checkForWarnings
    if [[ $newWarns == 0 ]] ; then
      echo "{color:green}+1{color} ${TASKNAME}" >> $SUMMARYFILE
    else
      echo "{color:red}-1{color} ${TASKNAME}" >> $SUMMARYFILE
    fi
    for line in "${REPORT[@]}" ; do
      echo ".    ${line}" >> $SUMMARYFILE
    done
    ;;
esac

exit 0
