#!/bin/bash
# get script's current absolute directory via subshell
_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# include boilerplate & util funcs
# shellcheck source=util.sh
source "${_dir}/util.sh"
# disable tracing set by util
set +x

### set defaults
GIT_BRANCH="${GIT_BRANCH:-"$(git branch --show-current)"}"
LINTER_EMAIL="${LINTER_EMAIL:-'admin-services@twitch.tv'}"
LINTER_NAME="${LINTER_NAME:-'Linter'}"
LINTER_SUBJECT="${LINTER_SUBJECT:-"style: autocorrect"}"

### run rubocpop normally
if bundle exec rubocop --parallel ; then
  # remove the git repo so we don't bake it into the docker image
  (rm -rf .git/)
else
  # store the failing exit code for later
  code=$?
  # 1 is a lint failure, 2 is a failure in the underlying machinery
  [ lint_fail="${code}" == 'lint_fail=1' ] || fail! "rubocop exited with code ${code}; Not a lint error"

  # make sure we have the freshest origin head to compare against
  # shellcheck disable=SC2207
  fetch=($(git fetch origin "${GIT_BRANCH}" --verbose 2>&1)) 
  # check fetch's status flag on the last line
  fetch_flag="${fetch[-1]:1:1}"
  # '=' means '[up to date]'
  # immediately exit when the fetch branch is not up to date; we can't make a safe decision
  [ "${fetch_flag}"x == '=x' ] || fail! "${fetch[*]}"

  # get the commit hashes for our local head and the freshly fetched origin head
  refs="$(git rev-parse HEAD FETCH_HEAD)"
  # de-dupe the two lines and check the resulting line count
  unique_refs="$(echo "${refs}" | uniq | wc -l)"
  # strip leading spaces from the result
  unique_refs="${unique_refs#"${unique_refs%%[![:space:]]*}"}"
  # one line means the ref hashes are the same, and we can continue.
  # two means our HEAD isn't in sync with the newest, and we should abandon the branch.
  [ in_sync="${unique_refs}" == 'in_sync=1' ] || fail! "HEADS out of sync"

  ### We're good to attempt a correction!
  # run rubocop again, now in autocorrect mode
  # store the run result for later use in the commit body
  commit="$(bundle exec rubocop --format clang -a)"
  # loudly stage the changed ruby files for commit
  git add -v ./*.rb
  # commit the result to the local repo
  git -c "user.email=${LINTER_EMAIL}" -c "user.name=${LINTER_NAME}" commit -m "${LINTER_SUBJECT}" -m "${commit}";
  # push the changeset to origin
  git push origin HEAD:"${GIT_BRANCH}"
  # end the current run
  fail! "${commit:+${commit}$'\n\n'}Submitted corrections for next run; Shutting down." "${code}"
fi

exit 0
