#!/bin/bash

show_help() {
  printf "Usage:\n"
  printf "  openwisp-utils-qa-checks --help\n"
  printf "  openwisp-utils-qa-checks {--migration-path <path> [--migrations-to-ignore <int>] | --skip-checkmigrations}\n"
  printf "            {[--message <commit-message>] | --skip-checkcommit}\n"
  printf "            {[--migration-module <module>] | --skip-checkmakemigrations}\n"
  printf "            [--skip-checkendline]\n"
  printf "            [--skip-flake8]\n"
  printf "            [--skip-isort]\n"
  printf "\n"
  printf "Runs all checks for quality assurance. Unneeded checks may be skipped by passing --skip-<check-name> argument.\n"
  printf "\n"
  printf "General options:\n"
  printf "  --help\t\t\t: Show this help text\n"
  printf "Migration check options:\n"
  printf "  --migration-path <path>\t: Path to migrations/ folder\n"
  printf "  --migrations-to-ignore <int>\t: Number of migrations after which checking of migration file names should begin,\n"
  printf "\t\t\t\t  say, if checking needs to start after 0003_auto_20150410_3242.py value should be 3\n"
  printf "  --skip-checkmigrations\t: Skip migration name check\n"
  printf "  You can do multiple migration check by passing the arguments with space-delimited string array.\n"
  printf "Commit name check options:\n"
  printf "  --message <commit-message>\t: Commit message (by default is equal to latest commit name)\n"
  printf "  --migration-module <module>\t: Name of Migration Module\n"
  printf "  --skip-checkmakemigrations\t: Skip make migration check\n"
  printf "  --skip-checkcommit\t\t: Skip commit check\n"
  printf "Blank endlines check options:\n"
  printf "  --skip-checkendline\t\t: Skip blank endlines check\n"
  printf "Flake8 check options:\n"
  printf "  --skip-flake8\t\t\t: Skip flake8 check\n"
  printf "Isort check options:\n"
  printf "  --skip-isort\t\t\t: Skip isort check\n"
}

echoerr() { echo "$@" 1>&2; }

runcheckendline() {
  echo "Running blank endline check"
  flag=0
  for i in $(find . -type f ! -path "*/*.egg-info/*" \
    ! -path "./.*" \
    ! -path "*.min.*" \
    ! -path "*.svg" -exec grep -Iq . {} \; -and -print); do
    if [ "$(tail -c 1 $i)" != "" ]; then
      echo "$i needs newline at the end"
      flag=1
    fi
  done
  if [ $flag -ne 0 ]; then
    echoerr "ERROR: Blank endline check failed!"
    FAILURE=1
  else
    echo "SUCCESS: Blank endline check successful!"
  fi
}

runcheckmigrations() {
  if [ "$MIGRATION_PATH" == "" ]; then
    echoerr "ERROR: No migration path specified!"
    FAILURE=1
    return
  fi
  for i in "${!MIGRATION_PATH[@]}"
  do
    path="${MIGRATION_PATH[$i]}"
    ignore="${MIGRATIONS_TO_IGNORE[$i]}"
    ignore="`[ $ignore ] && echo \"$ignore\" || echo 0`"
    checkmigrations --migration-path "$path" --migrations-to-ignore "$ignore" \
      && echo "SUCCESS: Migration name check on \"$path\" with migrations-to-ignore: $ignore successful!" \
      || { echoerr "ERROR: Migration name check on \"$path\" with migrations-to-ignore: $ignore failed!"; FAILURE=1; }
  done
}

runflake8() {
  flake8 && echo "SUCCESS: Flake8 check successful!" \
    || { echoerr "ERROR: Flake8 check failed!"; FAILURE=1; }
}

runisort() {
  echo "Running isort check"
  isort --check-only --recursive --diff \
    && echo "SUCCESS: Isort check successful!" \
    || { echoerr "ERROR: Isort check failed!"; FAILURE=1; }
}

runcheckcommit() {
  [ -n "$TRAVIS_PULL_REQUEST" ] || TRAVIS_PULL_REQUEST="false"
  if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
    echo "Running commit message check"
    checkcommit --message "$COMMIT_MESSAGE" \
    && echo "SUCCESS: Commit name check successful!" \
    || { printf "Checking commit message:\n\n"; printf "%s\n\n" "$COMMIT_MESSAGE"; echoerr "ERROR: Commit name check failed!"; FAILURE=1; }
  else
    echo "SUCCESS: Commit name check successful!"
  fi
}

runcheckpendingmigrations() {
  if [ ! -f "./tests/manage.py" ]; then
    echo "File manage.py not found, skipping Make Migration Check."
  else
    OUTPUT=$(python tests/manage.py makemigrations --dry-run $MODULE)
    echo $OUTPUT
    echo $OUTPUT | grep "No changes detected" &> /dev/null \
      && echo "SUCCESS: Migrations check successful!" \
      || { echoerr "ERROR: Migrations check failed! Models' changes not migrated, please run `./manage.py makemigrations` to solve the issue!"; FAILURE=1; }
  fi
}

## Main

SKIP_CHECKENDLINE=false
SKIP_CHECKMIGRATIONS=false
SKIP_MAKEMIGRATIONS=false
SKIP_FLAKE8=false
SKIP_ISORT=false
SKIP_CHECKCOMMIT=false
MIGRATION_PATH=""
MIGRATIONS_TO_IGNORE="0"
COMMIT_MESSAGE=$(git log $TRAVIS_PULL_REQUEST_SHA --format=%B -n 1)
FAILURE=0
MODULE=""

while [ "$1" != "" ]; do
  case "$1" in
  --skip-checkendline)
    SKIP_CHECKENDLINE=true
    ;;
  --skip-checkmigrations)
    SKIP_CHECKMIGRATIONS=true
    ;;
  --migration-path)
    shift
    MIGRATION_PATH=($1)
    ;;
  --migrations-to-ignore)
    shift
    MIGRATIONS_TO_IGNORE=($1)
    ;;
  --skip-flake8)
    SKIP_FLAKE8=true
    ;;
  --skip-isort)
    SKIP_ISORT=true
    ;;
  --skip-checkcommit)
    SKIP_CHECKCOMMIT=true
    ;;
  --message)
    shift
    COMMIT_MESSAGE="$1"
    ;;
  --skip-checkmakemigrations)
    SKIP_MAKEMIGRATIONS=true
    ;;
  --migration-module)
    shift
    MODULE="$1"
    ;;
  --help)
    show_help
    exit
    ;;
  *)
    printf "Unknown argument: %s\n" "$1"
    printf "\n"
    show_help
    exit 1
    ;;
  esac
  shift
done

set -e

if ! $SKIP_CHECKENDLINE; then
  runcheckendline
fi

if ! $SKIP_CHECKMIGRATIONS; then
  runcheckmigrations
fi

if ! $SKIP_FLAKE8; then
  runflake8
fi

if ! $SKIP_ISORT; then
  runisort
fi

if ! $SKIP_CHECKCOMMIT; then
  runcheckcommit
fi

if ! $SKIP_MAKEMIGRATIONS; then
  runcheckpendingmigrations
fi

exit $FAILURE
