#!/usr/bin/env bash

function error_handler() {
  >&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
  exit "$2"
}
trap 'error_handler ${LINENO} $?' ERR
set -o errtrace -o errexit -o nounset -o pipefail

python_projects=(
  spiffworkflow-backend
)

react_projects=(
  spiffworkflow-frontend
)

subcommand="${1:-}"

if [[ "$subcommand" == "pre" ]]; then
  if [[ -n "$(git status --porcelain SpiffWorkflow)" ]]; then
    echo "SpiffWorkflow has uncommitted changes. Running its test suite."
    pushd SpiffWorkflow
    make tests-par # run tests in parallel
    popd
  fi
fi

function get_python_dirs() {
  (git ls-tree -r HEAD --name-only | grep -E '\.py$' | awk -F '/' '{print $1}' | sort | uniq | grep -v '\.' | grep -Ev '^(bin|migrations)$') || echo ''
}

function run_autoflake() {
  # checking command -v autoflake8 is not good enough, since the asdf shim may be installed, which will make command -v succeed,
  # but autoflake8 may not have been pip installed inside the correct version of python.
  if ! autoflake8 --help >/dev/null ; then
    pip install autoflake8
    asdf reshim python
  fi

  if ! autoflake --help >/dev/null ; then
    pip install autoflake
    asdf reshim python
  fi

  if ! autopep8 --help >/dev/null ; then
    pip install autopep8
    asdf reshim python
  fi

  python_dirs=$(get_python_dirs)
  python_files=$(find $python_dirs -type f -name "*.py" ! -name '.null-ls*' ! -name '_null-ls*')
  autoflake8 --in-place --remove-unused-variables --remove-duplicate-keys --expand-star-imports --exit-zero-even-if-changed $python_files
  autoflake --in-place --remove-all-unused-imports $python_files
  autopep8 --in-place $python_files
}

function run_pre_commmit() {
  poetry run pre-commit run --verbose --all-files
}

for react_project in "${react_projects[@]}" ; do
  # if pre, only do stuff when there are changes
  if [[ "$subcommand" != "pre" ]] || [[ -n "$(git status --porcelain "$react_project")" ]]; then
    pushd "$react_project"
    npm run lint:fix
    popd
  fi
done

for python_project in "${python_projects[@]}" ; do
  if [[ "$subcommand" != "pre" ]] || [[ -n "$(git status --porcelain "$python_project")" ]]; then
    pushd "$python_project"
    run_autoflake || run_autoflake
    popd
  fi
done

if [[ "$subcommand" != "pre" ]] || [[ -n "$(git status --porcelain "spiffworkflow-backend")" ]]; then
  # rune_pre_commit only applies to spiffworkflow-backend at the moment
  run_pre_commmit || run_pre_commmit
fi

for python_project in "${python_projects[@]}"; do
  if [[ "$subcommand" != "pre" ]] || [[ -n "$(git status --porcelain "$python_project")" ]]; then
    pushd "$python_project"
    poetry install
    poetry run mypy $(get_python_dirs)
    poetry run coverage run --parallel -m pytest
    popd
  fi
done