#!/usr/bin/env bash

## Create pre-commit symlink if unset ##
GITDIR="";
if [ -d .git ]; then
  GITDIR=".git";
elif [ -f .git ]; then
  GITDIR=$(sed -n '/^gitdir:/{ s|.*: ||; p; }' .git);
fi
if [ ! -d "$GITDIR" ]; then
  echo "${0##*/}: error: unable to find git directory" 1>&2;
  exit 1;
fi
if [ ! -h "$GITDIR/hooks/pre-commit" ]; then
  if [ $(realpath --help 2>&1 | grep -c relative) != 0 ]; then
    HOOK=$(realpath --relative-to="$GITDIR/hooks" ./githook-pre-commit);
  else
    HOOK=$(readlink -f ./githook-pre-commit);
  fi
  ln -fs "$HOOK" "$GITDIR/hooks/pre-commit";
  echo "${0##*/}: creating git pre-commit hook symlink" 1>&2;
  exit 1;
fi


## Check files that changed ##
FILES=( $(git status --porcelain | sed -r 's|^ |_|; s|^(.) |\1_|; s|^(R[_M]) .* ->|\1|;' | grep -E '^([MRA]|.M)') );
PYLINT=$(which pylint pylint3 | head -n 1);
PYLINT+=" --errors-only --disable=no-member";
PYFILES=();

check_change_after_staged () {
  [ "${2:1:1}" = "M" ] &&
    echo "${0##*/}: error: changed after staged: $1" 1>&2 &&
    exit 1;
}

n=1;
while [ "$n" -lt "${#FILES[@]}" ]; do
  check_change_after_staged "${FILES[$n]}" "${FILES[$((n-1))]}";
  case "${FILES[$n]}" in
    *.py )
      if [ "${FILES[$n]}" != "sphinx/conf.py" ]; then
        PYFILES+=("${FILES[$n]}")
      fi
      ;;
    .circleci/config.yml )
      echo "${0##*/}: circleci config validate -c .circleci/config.yml" 1>&2;
      circleci config validate -c .circleci/config.yml;
  esac
  [ "$?" != "0" ] && exit 1;
  n=$((n+2));
done

if [ "${#PYFILES[@]}" -gt 0 ]; then
  echo "${0##*/}: mypy jsonargparse/*.py jsonargparse_tests/*.py" 1>&2;
  mypy jsonargparse/*.py jsonargparse_tests/*.py;
  [ "$?" != "0" ] && exit 1;
  echo "${0##*/}: pycodestyle ${PYFILES[@]}" 1>&2;
  pycodestyle "${PYFILES[@]}";
  [ "$?" != "0" ] && exit 1;
  echo "${0##*/}: $PYLINT ${PYFILES[@]}" 1>&2;
  $PYLINT "${PYFILES[@]}";
  [ "$?" != "0" ] && exit 1;
fi

## Run doc tests ##
sphinx-build -M doctest sphinx sphinx/_build sphinx/README.rst
[ "$?" != "0" ] && exit 1;

## Run unit tests ##
./setup.py test_coverage;
[ "$?" != "0" ] && exit 1;

## Only when bumping version ##
if [ "${BUMPVERSION_NEW_VERSION+x}" != "" ]; then
  ## Check changelog ##
  CHANGELOG=$(grep -E '^v.+\..+\..+ \(....-..-..\)' CHANGELOG.rst | head -n 1);
  EXPECTED="v$BUMPVERSION_NEW_VERSION ($(date -u +%Y-%m-%d))";
  if [ "$CHANGELOG" != "$EXPECTED" ] && [ $(echo $BUMPVERSION_NEW_VERSION | grep -cE '[0-9.]+(\.dev|rc)[0-9]+') = 0 ]; then
    if [ ! -z "${BUMPVERSION_UPDATE_CHANGELOG+x}" ] && [ $(grep -c "^v$BUMPVERSION_NEW_VERSION " CHANGELOG.rst) = 1 ]; then
      sed -i "s|^v$BUMPVERSION_NEW_VERSION .*|$EXPECTED|" CHANGELOG.rst;
      git add CHANGELOG.rst;
    else
      echo "${0##*/}: Expected latest release in CHANGELOG.rst to be '$EXPECTED'. Set BUMPVERSION_UPDATE_CHANGELOG to auto update." 1>&2;
      exit 1;
    fi
  fi

  ## Check wheel ok for pypi ##
  ./setup.py bdist_wheel;
  twine check dist/*.whl;
  [ "$?" != "0" ] && exit 1;
fi

exit 0;
