#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

# SHELLDOC-IGNORE

SPOTBUGS_HOME=${SPOTBUGS_HOME:-}
ANT_SPOTBUGSXML=${ANT_SPOTBUGSXML:-}
SPOTBUGS_WARNINGS_FAIL_PRECHECK=false
SPOTBUGS_TABLE_DUPE=false

if [[ -z "${SPOTBUGS_HOME}" && -n "${FINDBUGS_HOME}" ]]; then
  SPOTBUGS_MODE=findbugs
else
  SPOTBUGS_MODE=spotbugs
fi

add_test_type spotbugs

function spotbugs_deprecate_test_type
{
  if [[ "${SPOTBUGS_MODE}" == spotbugs ]]; then
    if replace_test_type spotbugs findbugs; then
      yetus_error "WARNING: Found both spotbugs and findbugs. Disabling findbugs."
      SPOTBUGS_TABLE_DUPE=true
    fi
  else
    if replace_test_type findbugs spotbugs; then
      yetus_error "WARNING: spotbugs has deprecated findbugs, but only found findbugs."
    fi
  fi
}

function spotbugs_usage
{
  yetus_add_option "--spotbugs-home=<path>" "SpotBugs home directory (default \${SPOTBUGS_HOME})"
  yetus_add_option "--spotbugs-strict-precheck" "If there are SpotBugs warnings during precheck, fail"
}

function spotbugs_parse_args
{
  declare i

  for i in "$@"; do
    case ${i} in
    --spotbugs-home=*)
      SPOTBUGS_HOME=${i#*=}
    ;;
    --spotbugs-strict-precheck)
      SPOTBUGS_WARNINGS_FAIL_PRECHECK=true
    ;;
    esac
  done
}

## @description  initialize the spotbugs plug-in
## @audience     private
## @stability    evolving
## @replaceable  no
function spotbugs_initialize
{
  if [[ "${SPOTBUGS_MODE}" == findbugs ]]; then
    FINDBUGS_HOME=${SPOTBUGS_HOME:-${FINDBUGS_HOME}}
  fi

  if declare -f maven_add_install >/dev/null 2>&1; then
    maven_add_install "${SPOTBUGS_MODE}"
  fi
}

function spotbugs_filefilter
{
  declare filename=$1

  if [[ ${BUILDTOOL} == maven
    || ${BUILDTOOL} == ant ]]; then
    if [[ ${filename} =~ \.java$
      || ${filename} =~ (^|/)${SPOTBUGS_MODE}-exclude.xml$ ]]; then
      add_test "${SPOTBUGS_MODE}"
    fi
  fi
}

function spotbugs_precheck
{
  declare exec
  declare status=0

  if [[ -z ${SPOTBUGS_HOME} ]]; then
    yetus_error "SPOTBUGS_HOME (or FINDBUGS_HOME) was not specified."
    status=1
  else
    for exec in computeBugHistory \
                convertXmlToText \
                filterBugs \
                setBugDatabaseInfo\
                unionBugs; do
      if ! verify_command "${exec}" "${SPOTBUGS_HOME}/bin/${exec}"; then
        status=1
      fi
    done
  fi
  if [[ ${status} == 1 ]]; then
    add_vote_table 0 "${SPOTBUGS_MODE}" "${SPOTBUGS_MODE} executables are not available."
    delete_test "${SPOTBUGS_MODE}"
  fi
}

## @description  Run the maven spotbugs plugin and record found issues in a bug database
## @audience     private
## @stability    evolving
## @replaceable  no
## @return       0 on success
## @return       1 on failure
## @param        repostatus
function spotbugs_runner
{
  declare name=$1
  declare module
  declare result=0
  declare fn
  declare warnings_file
  declare i=0
  declare savestop
  declare retval


  personality_modules "${name}" "${SPOTBUGS_MODE}"

  "${BUILDTOOL}_modules_worker" "${name}" "${SPOTBUGS_MODE}"

  if [[ ${UNSUPPORTED_TEST} = true ]]; then
    return 0
  fi

  echo ""
  echo "Building ${SPOTBUGS_MODE} database(s) using ${SPOTBUGS_HOME} for executables."
  echo ""

  if [[ "${SPOTBUGS_TABLE_DUPE}" == true ]] && [[ "${name}" == branch ]]; then
    add_vote_table 0 spotbugs "Both FindBugs and SpotBugs are enabled, using SpotBugs."
  fi

  #shellcheck disable=SC2153
  until [[ ${i} -eq ${#MODULE[@]} ]]; do
    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
      ((result=result+1))
      ((i=i+1))
      continue
    fi
    start_clock
    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
    module="${MODULE[${i}]}"
    fn=$(module_file_fragment "${module}")

    if [[ "${module}" == . ]]; then
      module=root
    fi

    case ${BUILDTOOL} in
      maven)
        targetfile="${SPOTBUGS_MODE}Xml.xml"
      ;;
      ant)
        targetfile="${ANT_SPOTBUGSXML}"
      ;;
    esac

    buildtool_cwd "${i}"

    files=()
    while read -r line; do
      files+=("${line}")
    done < <(find . -name "${targetfile}")

    warnings_file="${PATCH_DIR}/${name}-${SPOTBUGS_MODE}-${fn}-warnings"

    if [[ "${#files[@]}" -lt 1 ]]; then
      module_status ${i} 0 "" "${name}/${module} no ${SPOTBUGS_MODE} output file (${targetfile})"
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    elif [[ "${#files[@]}" -eq 1 ]]; then
      cp -p "${files[0]}" "${warnings_file}.xml"
    else
      "${SPOTBUGS_HOME}/bin/unionBugs" -withMessages -output "${warnings_file}.xml" "${files[@]}"
    fi

    popd >/dev/null || return 1

    if [[ ${name} == branch ]]; then
      "${SPOTBUGS_HOME}/bin/setBugDatabaseInfo" -name "${PATCH_BRANCH}" \
          "${warnings_file}.xml" "${warnings_file}.xml"
      retval=$?
    else
      "${SPOTBUGS_HOME}/bin/setBugDatabaseInfo" -name patch \
          "${warnings_file}.xml" "${warnings_file}.xml"
      retval=$?
    fi

    if [[ ${retval} != 0 ]]; then
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      module_status ${i} -1 "" "${name}/${module} cannot run setBugDatabaseInfo from ${SPOTBUGS_MODE}"
      ((result=result+1))
      ((i=i+1))
      continue
    fi

    if [[ ! -f "${warnings_file}.xml" ]]; then
      module_status ${i} 0 "" "${name}/${module} no data in SpotBugs/FindBugs output file (${targetfile})"
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    if ! "${SPOTBUGS_HOME}/bin/convertXmlToText" -html \
      "${warnings_file}.xml" \
      "${warnings_file}.html"; then
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      module_status ${i} -1 "" "${name}/${module} cannot run convertXmlToText from ${SPOTBUGS_MODE}"
      ((result=result+1))
    fi

    if [[ -z ${SPOTBUGS_VERSION}
        && ${name} == branch ]]; then
      SPOTBUGS_VERSION=$("${GREP}" -i "BugCollection version=" "${warnings_file}.xml" \
        | cut -f2 -d\" \
        | cut -f1 -d\" )
      if [[ -n ${SPOTBUGS_VERSION} ]]; then
        add_footer_table "${SPOTBUGS_MODE}" "v${SPOTBUGS_VERSION}"
      fi
    fi

    ((i=i+1))
  done

  return ${result}
}

## @description  Track pre-existing spotbugs warnings
## @audience     private
## @stability    evolving
## @replaceable  no
## @return       0 on success
## @return       1 on failure
function spotbugs_preapply
{
  declare fn
  declare module
  declare modindex=0
  declare warnings_file
  declare module_spotbugs_warnings
  declare result=0
  declare msg

  if ! verify_needed_test "${SPOTBUGS_MODE}"; then
    return 0
  fi

  big_console_header "${SPOTBUGS_MODE} detection: ${PATCH_BRANCH}"

  spotbugs_runner branch
  result=$?

  if [[ ${UNSUPPORTED_TEST} = true ]]; then
    return 0
  fi

  if [[ "${SPOTBUGS_MODE}" == findbugs ]]; then
    add_vote_table 0 spotbugs "Used deprecated FindBugs config; considering switching to SpotBugs."
  fi

  until [[ ${modindex} -eq ${#MODULE[@]} ]]; do
    if [[ ${MODULE_STATUS[${modindex}]} == -1 ]]; then
      ((result=result+1))
      ((modindex=modindex+1))
      continue
    fi

    module=${MODULE[${modindex}]}
    start_clock
    offset_clock "${MODULE_STATUS_TIMER[${modindex}]}"
    fn=$(module_file_fragment "${module}")

    if [[ "${module}" == . ]]; then
      module=root
    fi

    warnings_file="${PATCH_DIR}/branch-${SPOTBUGS_MODE}-${fn}-warnings"
    if [[ ! -f "${warnings_file}.xml" ]]; then
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${modindex}]=${savestop}
      ((modindex=modindex+1))
      continue
    fi

    # shellcheck disable=SC2016
    module_spotbugs_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
        "${PATCH_BRANCH}" \
        "${warnings_file}.xml" \
        "${warnings_file}.xml" \
        | "${AWK}" '{print $1}')

    if [[ ${module_spotbugs_warnings} -gt 0 ]] ; then
      msg="${module} in ${PATCH_BRANCH} has ${module_spotbugs_warnings} extant ${SPOTBUGS_MODE} warnings."
      if [[ "${SPOTBUGS_WARNINGS_FAIL_PRECHECK}" = "true" ]]; then
        module_status ${modindex} -1 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
        ((result=result+1))
      elif [[ "${BUILDMODE}" = full ]]; then
        module_status ${modindex} -1 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
        ((result=result+1))
        populate_test_table "${SPOTBUGS_MODE}" "module:${module}"
        #shellcheck disable=SC2162
        while read line; do
          firstpart=$(echo "${line}" | cut -f2 -d:)
          secondpart=$(echo "${line}" | cut -f9- -d' ')
          add_test_table "" "${firstpart}:${secondpart}"
        done < <("${SPOTBUGS_HOME}/bin/convertXmlToText" "${warnings_file}.xml")
      else
        module_status ${modindex} 0 "branch-${SPOTBUGS_MODE}-${fn}-warnings.html" "${msg}"
      fi
    fi

    savestop=$(stop_clock)
    MODULE_STATUS_TIMER[${modindex}]=${savestop}
    ((modindex=modindex+1))
  done
  modules_messages branch "${SPOTBUGS_MODE}" true

  if [[ ${result} != 0 ]]; then
    return 1
  fi
  return 0
}

## @description  Verify patch does not trigger any spotbugs warnings
## @audience     private
## @stability    evolving
## @replaceable  no
## @return       0 on success
## @return       1 on failure
function spotbugs_postinstall
{
  declare module
  declare fn
  declare combined_xml
  declare branchxml
  declare patchxml
  declare newbugsbase
  declare fixedbugsbase
  declare branch_warnings
  declare patch_warnings
  declare fixed_warnings
  declare line
  declare firstpart
  declare secondpart
  declare i=0
  declare result=0
  declare savestop
  declare summarize=true
  declare statstring

  if ! verify_needed_test "${SPOTBUGS_MODE}"; then
    return 0
  fi

  big_console_header "${SPOTBUGS_MODE} detection: ${BUILDMODE}"

  spotbugs_runner patch

  if [[ ${UNSUPPORTED_TEST} = true ]]; then
    return 0
  fi

  until [[ $i -eq ${#MODULE[@]} ]]; do
    if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
      ((result=result+1))
      ((i=i+1))
      continue
    fi

    start_clock
    offset_clock "${MODULE_STATUS_TIMER[${i}]}"
    module="${MODULE[${i}]}"

    buildtool_cwd "${i}"

    fn=$(module_file_fragment "${module}")

    if [[ "${module}" == . ]]; then
      module=root
    fi

    combined_xml="${PATCH_DIR}/combined-${SPOTBUGS_MODE}-${fn}.xml"
    branchxml="${PATCH_DIR}/branch-${SPOTBUGS_MODE}-${fn}-warnings.xml"
    patchxml="${PATCH_DIR}/patch-${SPOTBUGS_MODE}-${fn}-warnings.xml"

    if [[ -f "${branchxml}" ]]; then
      # shellcheck disable=SC2016
      branch_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
          "${PATCH_BRANCH}" \
          "${branchxml}" \
          "${branchxml}" \
          | ${AWK} '{print $1}')
    else
      branchxml=${patchxml}
    fi

    newbugsbase="${PATCH_DIR}/new-${SPOTBUGS_MODE}-${fn}"
    fixedbugsbase="${PATCH_DIR}/fixed-${SPOTBUGS_MODE}-${fn}"

    if [[ ! -f "${branchxml}" ]] && [[ ! -f "${patchxml}" ]]; then
      module_status ${i} 0 "" "${module} has no data from ${SPOTBUGS_MODE}"
      ((result=result+1))
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    echo ""

    if ! "${SPOTBUGS_HOME}/bin/computeBugHistory" -useAnalysisTimes -withMessages \
            -output "${combined_xml}" \
            "${branchxml}" \
            "${patchxml}"; then
      module_status ${i} -1 "" "${module} cannot run computeBugHistory from ${SPOTBUGS_MODE}"
      ((result=result+1))
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    # shellcheck disable=SC2016
    patch_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first \
        "patch" \
        "${patchxml}" \
        "${patchxml}" \
        | ${AWK} '{print $1}')

    #shellcheck disable=SC2016
    add_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -first patch \
        "${combined_xml}" "${newbugsbase}.xml" | ${AWK} '{print $1}')
    retval=$?
    if [[ ${retval} != 0 ]]; then
      module_status ${i} -1 "" "${module} cannot run filterBugs (#1) from ${SPOTBUGS_MODE}"
      ((result=result+1))
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    #shellcheck disable=SC2016
    fixed_warnings=$("${SPOTBUGS_HOME}/bin/filterBugs" -fixed patch \
        "${combined_xml}" "${fixedbugsbase}.xml" | ${AWK} '{print $1}')
    retval=$?
    if [[ ${retval} != 0 ]]; then
      module_status ${i} -1 "" "${module} cannot run filterBugs (#2) from ${SPOTBUGS_MODE}"
      ((result=result+1))
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    statstring=$(generic_calcdiff_status "${branch_warnings}" "${patch_warnings}" "${add_warnings}")

    if ! "${SPOTBUGS_HOME}/bin/convertXmlToText" -html "${newbugsbase}.xml" \
        "${newbugsbase}.html"; then
      module_status ${i} -1 "" "${module} cannot run convertXmlToText from ${SPOTBUGS_MODE}"
      ((result=result+1))
      savestop=$(stop_clock)
      MODULE_STATUS_TIMER[${i}]=${savestop}
      ((i=i+1))
      popd >/dev/null || return 1
      continue
    fi

    if [[ ${add_warnings} -gt 0 ]] ; then
      populate_test_table FindBugs "module:${module}"
      #shellcheck disable=SC2162
      while read line; do
        firstpart=$(echo "${line}" | cut -f2 -d:)
        secondpart=$(echo "${line}" | cut -f9- -d' ')
        add_test_table "" "${firstpart}:${secondpart}"
      done < <("${SPOTBUGS_HOME}/bin/convertXmlToText" "${newbugsbase}.xml")

      module_status ${i} -1 "new-${SPOTBUGS_MODE}-${fn}.html" "${module} ${statstring}"
      ((result=result+1))
    elif [[ ${fixed_warnings} -gt 0 ]]; then
      module_status ${i} +1 "" "${module} ${statstring}"
      summarize=false
    fi
    savestop=$(stop_clock)
    MODULE_STATUS_TIMER[${i}]=${savestop}
    popd >/dev/null || return 1
    ((i=i+1))
  done

  modules_messages patch ${SPOTBUGS_MODE} "${summarize}"
  if [[ ${result} != 0 ]]; then
    return 1
  fi
  return 0
}

function spotbugs_rebuild
{
  declare repostatus=$1

  if [[ "${repostatus}" = branch || "${BUILDMODE}" = full ]]; then
    spotbugs_preapply
  else
    spotbugs_postinstall
  fi
}


##
## To be removed:  FindBugs instead of SpotBugs
##

add_test_type findbugs

function findbugs_usage
{
  yetus_add_option "--findbugs-home=<path>" "Findbugs home directory (default \${FINDBUGS_HOME})"
  yetus_add_option "--findbugs-strict-precheck" "If there are Findbugs warnings during precheck, fail"
}

function findbugs_parse_args
{
  declare i

  for i in "$@"; do
    case ${i} in
    --findbugs-home=*)
      SPOTBUGS_HOME=${i#*=}
    ;;
    --findbugs-strict-precheck)
      SPOTBUGS_WARNINGS_FAIL_PRECHECK=true
    ;;
    esac
  done
}

function findbugs_initialize
{
  SPOTBUGS_MODE="findbugs"
  ANT_SPOTBUGSXML=${ANT_FINDBUGSXML}
  SPOTBUGS_HOME=${FINDBUGS_HOME}
  spotbugs_initialize "$@"
}

function findbugs_filefilter
{
  spotbugs_initialize "$@"
}

function findbugs_rebuild
{
  spotbugs_rebuild "$@"
}