#!/bin/sh
#
# Check that the code follows a consistent code style
#

# Check for existence of indent, and error out if not present.
# On some *bsd systems the binary seems to be called gnunindent,
# so check for that first.

version=`gnuindent --version 2>/dev/null`
if test "x$version" = "x"; then
  version=`gindent --version 2>/dev/null`
  if test "x$version" = "x"; then
    version=`indent --version 2>/dev/null`
    if test "x$version" = "x"; then
      echo "GStreamer git pre-commit hook:"
      echo "Did not find GNU indent, please install it before continuing."
      exit 1
    else
      INDENT=indent
    fi
  else
    INDENT=gindent
  fi
else
  INDENT=gnuindent
fi

case `$INDENT --version` in
  GNU*)
      ;;
  default)
      echo "GStreamer git pre-commit hook:"
      echo "Did not find GNU indent, please install it before continuing."
      echo "(Found $INDENT, but it doesn't seem to be GNU indent)"
      exit 1
      ;;
esac

INDENT_PARAMETERS="--braces-on-if-line \
	--case-brace-indentation0 \
	--case-indentation2 \
	--braces-after-struct-decl-line \
	--line-length80 \
	--no-tabs \
	--cuddle-else \
	--dont-line-up-parentheses \
	--continuation-indentation4 \
	--honour-newlines \
	--tab-size8 \
	--indent-level2 \
	--leave-preprocessor-space"

echo "--Checking style--"
for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.c$"` ; do
    # nf is the temporary checkout. This makes sure we check against the
    # revision in the index (and not the checked out version).
    nf=`git checkout-index --temp ${file} | cut -f 1`
    newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1
    $INDENT ${INDENT_PARAMETERS} \
	$nf -o $newfile 2>> /dev/null
    # FIXME: Call indent twice as it tends to do line-breaks
    # different for every second call.
    $INDENT ${INDENT_PARAMETERS} \
        $newfile 2>> /dev/null
    diff -u -p "${nf}" "${newfile}"
    r=$?
    rm "${newfile}"
    rm "${nf}"
    if [ $r != 0 ] ; then
echo "================================================================================================="
echo " Code style error in: $file                                                                      "
echo "                                                                                                 "
echo " Please fix before committing. Don't forget to run git add before trying to commit again.        "
echo " If the whole file is to be committed, this should work (run from the top-level directory):      "
echo "                                                                                                 "
echo "   gst-indent $file; git add $file; git commit"
echo "                                                                                                 "
echo "================================================================================================="
        exit 1
    fi
done
echo "--Checking style pass--"

# This is an opt-in check, and can only be run from gst-build's devenv,
# as outside of it MESON_BUILD_ROOT will not be set.
#
# The idea is to build the cache, and check if it has unstaged changes.
# To accomodate for the git add -p case, where the developer will break
# down a large change set into multiple commits, this hook will only
# fail when there are no unstaged changes left to commit, in other
# cases it will only print a reminder that the cache needs committing.
if [ -v MESON_BUILD_ROOT ] && [ "$GST_CACHE_HOOK" == "enabled" ]; then
    echo "--Checking plugin cache--"
    toplevel=`git rev-parse --show-toplevel`
    repo_name=`basename $toplevel`
    target_name=`ninja -C $MESON_BUILD_ROOT -t targets all | grep "\/\<$repo_name\>\/.*\/gst_plugins_cache.json" | cut -d ":" -f 1`
    ninja -C $MESON_BUILD_ROOT $target_name
    cache_path=`git ls-files $toplevel/**gst_plugins_cache.json`
    git diff --quiet --exit-code -- $cache_path
    has_unstaged_cache_changes=$?
    git diff --quiet --exit-code -- ':!'$cache_path
    has_unstaged_non_cache_changes=$?

    if [ $has_unstaged_non_cache_changes != 0 ] ; then
        if [ $has_unstaged_cache_changes != 0 ]; then
            echo -e "\033[1;33mUnstaged cache changes, but working directory isn't clean, don't forget to commit the cache when you're done\033[0m"
        fi
    elif [ $has_unstaged_cache_changes != 0 ]; then
        echo -e "\033[1;31mUnstaged cache changes, but the working directory is clean, you must commit the cache\033[0m"
        exit 1
    else
    echo "--Checking plugin cache pass--"
    fi
fi
