#!/bin/bash

set -u

BASE_BIN=${BASE_BIN:-/usr/bin}

# command line handling
CMDLINE_OPTS=disable-checkbashism,disable-pep8,disable-perlcritic,disable-shellcheck
CMDLINE_OPTS+=,file-list,help

_opt_temp=$(getopt --name tap_tool_dispatcher -o -f+h --long $CMDLINE_OPTS -- "$@")
if [ $? -ne 0 ]; then
  echo "Try '$0 --help' for more information." >& 2
  exit 1
fi
eval set -- "$_opt_temp"

# defaults
_opt_checkbashism=true
_opt_pep8=true
_opt_perlcritic=true
_opt_shellcheck=true

usage() {
  echo "$0 - run code style quality tools in parallel

  Usage: $0 [<options>]

  Supported options:

   --disable-checkbashism  Disable checkbashism execution
   --disable-pep8          Disable pep8 execution
   --disable-perlcritic    Disable perlcritic execution
   --disable-shellcheck    Disable shellcheck execution
   -f|--file-list FILE     File with the list of files to check
   -h|--help               Display this usage information and exit
   "
}

while :; do
  case "$1" in
  --help|-h)
    usage ; exit 0;
    ;;
  --disable-checkbashism)
    _opt_checkbashism=false
    ;;
  --disable-pep8)
    _opt_pep8=false
    ;;
  --disable-perlcritic)
    _opt_perlcritic=false
    ;;
  --disable-shellcheck)
    _opt_shellcheck=false
    ;;
  --file-list|-f)
    [ -f "$2" ] || { echo "No $2 file found" >&2; exit 1; }
    FILE_LIST="$2"
    shift;
    ;;
  --)
    shift; break
    ;;
  *)
    echo "Internal getopt error! $1" >&2
    exit 1
    ;;
  esac
  shift
done

# sanity checks before executing anything
if [ -z "${REPORTS_DIRECTORY:-}" ] ; then
  export REPORTS_DIRECTORY='reports'
fi

if [ -z "${WORKSPACE:-}" ] ; then
  echo "Error: WORKSPACE unset, please run inside Jenkins. ">&2
  exit 1
fi

if ! [ -d source ] ; then
  echo "Error: no source directory found, please run inside Jenkins." >&2
  exit 1
fi

# start with clean report dir
rm -rf "${REPORTS_DIRECTORY}"

# set up a temporary file which executes the requested commands
TMPFILE="$(mktemp)" || exit 1

# GNU parallel supports the -v option, while parallel from moreutils doesn't
unset PARALLEL_OPTION
if parallel --version >/dev/null 2>&1 ; then
  PARALLEL_OPTION='-v'
fi

if [ -n "${FILE_LIST:-}" ] ; then
  LIST="sed 's#^#source/#g' < $FILE_LIST"
else
  LIST="find source -type f ! -path '*.svn*' ! -path '*.git/*' ! -name '.gitignore' -prune"
fi

echo "$LIST | parallel ${PARALLEL_OPTION:-} -- \\
  mkdir -p ${REPORTS_DIRECTORY}'/'{//} ';' \\" > "${TMPFILE}"

if ! [ -x "$(which checkbashisms)" ] ; then
  echo "*** Skipping checkbashism checks as tool checkbashisms isn't present ***"
else
  if $_opt_checkbashism ; then
    echo "${BASE_BIN}/checkbashism_tap '{}' '>' ${REPORTS_DIRECTORY}'/{}_checkbashism.tap' ';' \\" >> "${TMPFILE}"
  else
    echo "*** Skipping checkbashism tests as requested via --disable-checkbashism ***"
  fi
fi

if ! [ -x "$(which pep8)" ] ; then
  echo "*** Skipping pep8 checks as tool pep8 isn't present ***"
else
  if $_opt_pep8 ; then
    echo "${BASE_BIN}/pep8_tap '{}' '>' ${REPORTS_DIRECTORY}'/{}_pep8.tap' ';' \\" >> "${TMPFILE}"
  else
    echo "*** Skipping pep8 tests as requested via --disable-pep8 ***"
  fi
fi

if ! [ -x "$(which perlcritic)" ] ; then
  echo "*** Skipping perlcritic checks as tool perlcritic (package libperl-critic-perl) isn't present ***"
else
  if $_opt_perlcritic ; then
    echo "${BASE_BIN}/perlcritic_tap '{}' '>' ${REPORTS_DIRECTORY}'/{}_perlcritic.tap' ';' \\" >> "${TMPFILE}"
  else
    echo "*** Skipping perlcritic tests as requested via --disable-perlcritic ***"
  fi
fi

if ! [ -x "$(which shellcheck)" ] ; then
  echo "*** Skipping shellcheck checks as tool shellcheck isn't present ***"
else
  if $_opt_shellcheck ; then
    echo "${BASE_BIN}/shellcheck_tap '{}' '>' ${REPORTS_DIRECTORY}'/{}_shellcheck.tap' ';'" >> "${TMPFILE}"
  else
    echo "*** Skipping shellcheck tests as requested via --disable-shellcheck ***"
  fi
fi

# generate the executed script
bash "${TMPFILE}"
rm -f "${TMPFILE}"

echo "*** Getting rid of empty files ***"
find "${REPORTS_DIRECTORY}" -type f -empty -exec rm {} +

## END OF FILE #################################################################
