#!/bin/bash -e

MBD_HOME=~mini-buildd

# Use first found mirror from sources as default
_read_mirror()
{
	for s in /etc/apt/sources.list $(ls /etc/apt/sources.list.d/*.list 2>/dev/null | sort); do
		[ -z "${MIRROR}" ] || break
		MIRROR=$(grep "^deb " "${s}" 2>/dev/null | head -n1 | cut -d" " -f2)
	done
	read -p "Mirror: " -e -i "${MIRROR}" MIRROR
}

_head()
{
	printf "\n=> ${*}\n"
}

_check_prog()
{
	local path
	for path in $(printf "${PATH}" | tr ":" " "); do
		local prog="${path}/${1}"
		if [ -x "${prog}" ]; then
			printf "I: Found: ${prog}.\n"
			return 0
		fi
	done
	printf "E: '${1}' not found in path; please install.\n" >&2
	exit 1
}

PYPATH="$(readlink -f $(dirname $0))"
DJSETTINGS="doc.django_settings"
PYLINTRC="${PYPATH}/.pylintrc"

mbd_pyenv()
{
	printf "export PYTHONPATH=\"${PYPATH}\"\n"
	printf "export DJANGO_SETTINGS_MODULE=\"${DJSETTINGS}\"\n"
	printf "export PYLINTRC=\"${PYLINTRC}\""
}

pyenv()
{
	eval "$(mbd_pyenv)"
}

mbd_pep8()
{
	_check_prog pep8
	(
		set +e
		pyenv
		# squeeze version does not set an error exit status
		t=$(mktemp)
		trap "rm ${t}" EXIT
		pep8 --ignore=E501,E122 doc/conf.py doc/django_settings.py setup.py mini-buildd mini_buildd/ | tee "${t}"
		[ ! -s "${t}" ]
	)
}

mbd_pymisc()
{
	local f regex
	for f in mini-buildd $(find mini_buildd -type f -name "*.py"); do
		for regex in \
			^from\ __future__\ import\ unicode_literals \
			^\#\ -\\*-\ coding:\ utf-8\ -\\*-; do
			printf "Checking '${f}' for '${regex}'..."
			grep --quiet "${regex}" "${f}"
			printf "OK.\n"
		done
		printf "Checking '${f}' for wrong explicit unicode string literals..."
		if ! grep 'u"' "${f}"; then
			printf "OK.\n"
		else
			return 1
		fi
	done
}

mbd_pydoctests()
{
	(
		pyenv
		python -m doctest -v mini-buildd mini-buildd-tool mini_buildd/*.py
	)
}

mbd_pyflakes()
{
	_check_prog pyflakes
	(
		pyenv
		pyflakes mini-buildd mini_buildd/
	)
}

mbd_pylintgeneratedmembers()
{
	# Generate all identifiers with "has no xxx member"
	# error. These are most likely false-positive due to django
	# models.
	for o in $(${0} pylint | grep "has no.*member" | cut -d"'" -f4 | sort | uniq); do
		printf "${o},"
	done
	printf "\n"
}

mbd_pylint()
{
	[ "$(lsb_release -s -c)" != "squeeze" ] || { printf "W: Skipping pylint on squeeze\n" >&2; return; }
	_check_prog pylint
	(
		pyenv
		pylint --reports=no setup.py mini-buildd mini-buildd-tool mini_buildd/
	)
}

mbd_pychecker()
{
	_check_prog pychecker
	(
		pyenv
		pychecker mini-buildd mini-buildd-tool $(find mini_buildd/ -name "*.py")
	)
}

mbd_pydjangolint()
{
	_check_prog django-lint
	(
		pyenv
		! django-lint mini_buildd/ | grep --invert-match \
			-e "is actually a directory; consider splitting application" \
			-e "BooleanField with default=True will not be reflected in database" \
			-e "Naive tree structure implementation using ForeignKey('self')" \
			-e "ForeignKey missing related_name" \
			-e "URLField uses verify_exists=True default" \
			-e "Model has too many field" \
			-e "Bad option value" \
			-e "^\*"
	)
}

mbd_check()
{
	local tests="pep8 pymisc pydoctests pyflakes pylint pydjangolint"
	for t in ${tests}; do
		echo "=> mbd_${t}"
		mbd_${t}
	done
	printf "\nOK. Tests passed: %s\n" "${tests}"
}

mbd_sfood()
{
	_check_prog sfood
	(
		pyenv
		sfood --internal-only mini_buildd/ | sfood-graph | dot -Tpdf >dependency.pdf
		evince --fullscreen dependency.pdf
	)
}

mbd_doc()
{
	python setup.py build_sphinx --source-dir=build/sphinx
}

mbd_purge()
{
	_head "Purging ${MBD_HOME}"
	sudo dpkg --purge mini-buildd

	# @todo: Workaround only as long as mini-buildd doesn't yet do it
	sudo rm -v -f /etc/schroot/chroot.d/mini-buildd-*

	# Also test mini-buildd's internal sbuild key workaround
	sudo rm -v -f /var/lib/sbuild/apt-keys/*
}

mbd_update()
{
	set +e
	(
		set -e
		mbd_check
	)
	ret=$?
	[ ${ret} -eq 0 ] || read -p "Check failed. Continue anyway? [R]" dummy
	set -e

	_head "Checking changelog (must be unchanged)..."
	git diff-index --exit-code HEAD debian/changelog

	_head "Building snapshot..."
	git dch --snapshot --auto --ignore-branch
	git-buildpackage --git-ignore-new --git-ignore-branch -us -uc

	_head "Installing snapshot..."
	cat <<EOF | sudo debconf-set-selections --verbose -
mini-buildd mini-buildd/admin_password password admin
mini-buildd mini-buildd/options string --verbose --debug=exception,django
EOF
	sudo debi

	_head "Checking out orig changelog again..."
	git checkout debian/changelog
}

mbd_default()
{
	# copy to avoid perm problems
	cp ./mini_buildd/fixtures/${1}.json /tmp/fix.json
	sudo su - mini-buildd -c "mini-buildd --loaddata=/tmp/fix.json"
}

mbd_test()
{
	read -p "About to upload test packages. All configured? [ http://$(hostname -f):8066 ]" dummy
	(
		cd ./examples
		./packages.testbuild ${1}
	)
}

mbd_all()
{
	mbd_build
	mbd_purge
	mbd_install
	mbd_test
}

sep=" "
for c in $(compgen -A function | grep '^mbd_'); do
	ACTIONS+="${sep}${c:4}"
	sep="|"
done
trap "printf '\nUsage: ${0}${ACTIONS}[_arg1_arg2..] \n' >&2" ERR

[ "${*}" ]

for ACTION in ${*}; do
	func=$(echo "${ACTION}" | cut -d_ -f1)
	args=""
	if echo "${ACTION}" | grep -q "_"; then
		args=$(echo "${ACTION}" | cut -d_ -f2- | tr "_" " ")
	fi
	mbd_${func} ${args}
done
