#!/usr/bin/env bash
set -euo pipefail

repo_root="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [[ -z "${repo_root}" ]]; then
  echo "not inside a git repository" >&2
  exit 1
fi

cd "${repo_root}"

if [[ "${1:-}" == "--fetch" ]]; then
  git fetch origin --prune
fi

failed=0

check() {
  local title="$1"
  shift
  echo
  echo "==> ${title}"
  if ! "$@"; then
    failed=1
  fi
}

check_no_unmerged() {
  local unmerged
  unmerged="$(git diff --name-only --diff-filter=U)"
  if [[ -n "${unmerged}" ]]; then
    echo "${unmerged}"
    return 1
  fi
}

check_conflict_markers() {
  if command -v rg >/dev/null 2>&1; then
    rg -n '^(<<<<<<<|=======|>>>>>>>)' . \
      --glob '!.git' \
      --glob '!control/scripts/pre_submit_check.sh'
  else
    git ls-files -z | xargs -0 grep -nE '^(<<<<<<<|=======|>>>>>>>)'
  fi
  local status=$?
  if [[ ${status} -eq 1 ]]; then
    return 0
  fi
  return ${status}
}

check_task_index() {
  if [[ -f control/scripts/task_index.py ]]; then
    python3 control/scripts/task_index.py validate
  fi
}

check_upstream_distance() {
  if git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' >/dev/null 2>&1; then
    git rev-list --left-right --count '@{upstream}...HEAD' |
      awk '{print "behind_upstream="$1, "ahead_upstream="$2}'
  else
    echo "no upstream configured"
  fi
}

echo "Repository: ${repo_root}"
echo "Branch: $(git branch --show-current 2>/dev/null || echo detached)"

check "git status" git status --short --branch
check "upstream distance" check_upstream_distance
check "no unmerged paths" check_no_unmerged
check "no conflict markers" check_conflict_markers
check "task index is generated from items" check_task_index
check "unstaged diff whitespace" git diff --check
check "staged diff whitespace" git diff --cached --check

echo
if [[ ${failed} -ne 0 ]]; then
  echo "pre-submit check failed"
  exit 1
fi

echo "pre-submit check passed"
