#!/bin/sh

filter=$(git config hooks.filter)
validate=$(git config hooks.validate)
indentation=$(git config hooks.indentation)
temp=$(mktemp -p /dev/shm -d -t git-hook.XXXX)
export SRC_DIR=$(pwd)
export WORK_DIR=$(git rev-parse --show-toplevel)

export commit=commit

new() {
	git status --porcelain | grep -E '^AM|^M|^A' | sed 's/^[^ ]* *//'
}

check() {
	file=$2
	luajit -e "
	for line in assert(io.open('$file')):lines() do
		if not line:match('^%s*'):match('^$1*$') then
			print('File \x1b[31m$file\x1b[00m is incorrectly indented!')
			os.exit(1)
		end
	end"
}

get_marks() {
	git status --porcelain | cut --bytes 4- | while read file
	do
		if [ -e "$temp/index/$file" ]
		then
			grep -n -i no$commit "$temp/index/$file" | sed "s/:/ /" | while read line
			do
				echo "$file:$line"
			done
		fi
	done
}

git checkout-index --prefix="$temp/index/" --all

marks=$(get_marks)
if [ -n "$marks" ]
then
	/bin/echo -e "\x1b[31m'no$commit' mark(s) found:\x1b[0m"
	echo $marks
	rm -rf $temp
	exit 1
fi

cd $temp/index/

ln -s "$WORK_DIR"/.git/ .git
if [ -n "$filter" ]; then
	sh -c "$filter"
	git add --all
fi

case $indentation in
	tab|tabs)
		/bin/echo -e "\x1b[2mChecking indentation: \x1b[32mtabs"
		for file in $(new); do
			check '\t' $file || error=1
		done
		;;
	space|spaces)
		/bin/echo -e "\x1b[2mChecking indentation: \x1b[32mspaces"
		for file in $(new); do
			check ' ' $file || error=1
		done
		;;
	""|off)
		echo "Skipping indentation check"
		;;
	*)
		echo "Cannot check for indentation type \033[31m'$indentation'\033[00m"
		exit 1
		;;
esac

if [ -n "$validate" ]; then
	/bin/echo -e "\x1b[33mValidating commit\x1b[0m"
	/bin/echo -e "\x1b[2mλ $validate\x1b[0m"
	if sh -c "$validate"
	then
		/bin/echo -e "\x1b[32mValidation Passed!\x1b[0m"
	else
		error=1
		/bin/echo -e "\x1b[1;31mValidation Failed!\x1b[0m"
	fi
fi

rm .git

if [ -n "$error" ]
then exit 1
fi

cd "$WORK_DIR"
rm -rf $temp

hook=$(basename $0)
if [ -f "$WORK_DIR/.git/hooks/$hook" ]
then
	echo Running project-level hook: "$WORK_DIR"/.git/hooks/$hook
	"$WORK_DIR"/.git/hooks/$hook
	error=$?
	if [ -n "$error" ]
	then exit $error
	fi
fi