#!/bin/sh

set -e

if ! [ -r /etc/pkgos/pkgos.conf ] ; then
	echo "Could not read /etc/pkgos/pkgos.conf"
	exit 1
else
	. /etc/pkgos/pkgos.conf
fi

if [ "${1}" = "-h" ] ; then
	echo "This utility attemps to parse an OpenStack requirements.txt file"
	echo "as input, and produce a list of Debian dependencies as output."
	echo "Note that this is far from perfect, and that you *WILL* need to"
	echo "manually check for the dependencies. This is only a helper in"
	echo "order to gain some precious development time."
	echo ""
	echo "If this utility is called without a parameter, it will attempt"
	echo "to read the requirements.txt and test-requirements.txt file."
	echo "Otherwise, it takes the first argument as the file to parse."
	exit 0
fi

# Some packages should never be in the dependencies in Debian,
# as they are included in Python 2.7. If you find one that is
# missing, just add it to the list it here.
BLACK_LIST="discover argparse ordereddict"
is_blacklisted () {
	ISBLACKLISTED="no"
	for i in $BLACK_LIST ; do
		if [ "${i}" = "${1}" ] ; then
			ISBLACKLISTED="yes"
		fi
	done
}

# Some packages should never make it into the Build-Depends-Indep:,
# because they are already in Build-Depends:. Here's the list for it.
BUILD_DEPENDS_LIST="sphinx pbr"
is_build_depends () {
	ISBUILDDEPENDS="no"
	for i in ${BUILD_DEPENDS_LIST} ; do
		if [ "${i}" = ${1} ] ; then
			ISBUILDDEPENDS="yes"
		fi
	done
}

EPOC_1_IN="python-cinderclient python-keystoneclient python-glanceclient python-swiftclient python-oslo.config"
has_1_in_epoc () {
	HAS_1_IN_EPOC="no"
	for i in ${EPOC_1_IN} ; do
		if [ "${i}" = ${1} ] ; then
			HAS_1_IN_EPOC="yes"
		fi
	done
}

EPOC_2_IN="python-novaclient"
has_2_in_epoc () {
	HAS_2_IN_EPOC="no"
	for i in ${EPOC_2_IN} ; do
		if [ "${i}" = ${1} ] ; then
			HAS_2_IN_EPOC="yes"
		fi
	done
}

NO_PYTHON_PREFIX="alembic testrepository subunit websockify cliff-tablib"
is_python_prefixed () {
	PY_PREFIX="yes"
	for i in ${NO_PYTHON_PREFIX} ; do
		if [ "${i}" = "${1}" ] ; then
			PY_PREFIX="no"
		fi
	done
}

# Param: $1: input file
#        $2: if set, then the Build-Depends: programs will be removed (for example: sphinx, pbr, etc.)
parse_and_print () {
	INPUT_FILE=$1
	REMOVE_BUILD_DEPENDS="no"
	if [ -n "${2}" ] ; then
		REMOVE_BUILD_DEPENDS="yes"
	fi
	DEP_LIST=""
#	echo `cat ${INPUT_FILE} | grep -v '^#' | grep -v '^[ \t]*$' | awk '{print $1}' | tr '[:upper:]' '[:lower:]' | sed $EXP`
	for i in `cat ${INPUT_FILE} | grep -v '^#' | grep -v '^[ \t]*$' | awk '{print $1}' | tr '[:upper:]' '[:lower:]' | sed $EXP` ; do
#		echo "Line ---> $i"
		VERS=`echo $i | sed -e 's/^[-a-zA-Z0-9._]*//'`
		if [ -n "$VERS" ] ; then
			PKG=`echo $i | sed -e "s/$VERS//" | sed -e s/python-//`
		else
			PKG=`echo $i | sed -e s/python-//`
		fi
		PKG=`echo $PKG | sed -e s/_/-/`
		is_blacklisted $PKG
		ISBUILDDEPENDS="no"
		if [ REMOVE_BUILD_DEPENDS="yes" ] ; then
			is_build_depends $PKG
		fi
		if [ $ISBLACKLISTED = "no" ] && [ ${ISBUILDDEPENDS} = "no" ]; then
			is_python_prefixed ${PKG}
			if [ ${PY_PREFIX} = "yes" ] ; then
				PKG=python-$PKG
			fi
			# Convert the package name into lowercase, as Debian
			# doesn't have any upper case in package names
			PKG=`echo $PKG | tr '[:upper:]' '[:lower:]'`
			if [ -n "$VERS" ] && [ $PKG != "python-hacking" ] ; then
				# If there's a a version-depends, convert the pip style
				# of dependency to the Debian one (ie: >> instead of >)
				FIRST_CONSTR=`echo $VERS | cut -d, -f1`
				FIRST_NUMS=`echo $FIRST_CONSTR | sed -e 's/[<>=\!]*//'`
				FIRST_SIGN=`echo $FIRST_CONSTR | sed -e "s/${FIRST_NUMS}//"`
				if [ "${FIRST_SIGN}" = '<' ] ; then
					FIRST_SIGN='<<'
				fi
				if [ "${FIRST_SIGN}" = '>' ] ; then
					FIRST_SIGN='>>'
				fi
				has_1_in_epoc $PKG
				if [ "${HAS_1_IN_EPOC}" = "yes" ] ; then
					FIRST_NUMS="1:${FIRST_NUMS}"
				fi
				has_2_in_epoc $PKG
				if [ "${HAS_2_IN_EPOC}" = "yes" ] ; then
					FIRST_NUMS="2:${FIRST_NUMS}"
				fi
				# If there's a fake-jessie-mirror folder in /etc/pkgos
				# use that one with madison-lite to check if the version
				# of the package is already in Jessie.
				if [ -d /etc/pkgos/fake-jessie-mirror ] ; then
					STABLE_VERSION=`madison-lite -a all,amd64 --mirror /etc/pkgos/fake-${TARGET_DISTRO}-mirror ${PKG} | awk '{print $3}'`
					# Make sure that the package is in the stable repo
					if [ -z "${STABLE_VERSION}" ] ; then
						VERSION_TO_DEPEND_ON=" (${FIRST_SIGN} ${FIRST_NUMS})"
					else
						#echo "Comparing for ${PKG}: dpkg --compare-versions ${STABLE_VERSION} gt ${FIRST_NUMS}"
						if dpkg --compare-versions ${STABLE_VERSION} gt ${FIRST_NUMS} ; then
							VERSION_TO_DEPEND_ON=""
						else
							VERSION_TO_DEPEND_ON=" (${FIRST_SIGN} ${FIRST_NUMS})"
						fi
					fi
				else
					VERSION_TO_DEPEND_ON=" (${FIRST_SIGN} ${FIRST_NUMS})"
				fi
				if [ -z "${DEP_LIST}" ] ; then
					DEP_LIST="${PKG}${VERSION_TO_DEPEND_ON}"
					#echo " $PKG (${FIRST_SIGN} ${FIRST_NUMS}),"
				else
					DEP_LIST="${DEP_LIST}\n$PKG${VERSION_TO_DEPEND_ON}"
				fi
			else
				if [ -z "${DEP_LIST}" ] ; then
					DEP_LIST="$PKG"
				else
					#echo " $PKG,"
					DEP_LIST="${DEP_LIST}\n$PKG"
				fi
			fi
			#echo "Package: $PKG\t\tFirst sign: ${FIRST_SIGN}\t\tFirst num: ${FIRST_NUMS}..."
		fi
	done
}

# Param: $DEPS: the dependency list, one package per line
#        $1: the word for the package dep (ie: Depends: or Build-Depends-Indep:)
format_output () {
#	set -x
	SPACES_IN_FRONT=`echo "${1} " | sed -e 's/[a-zBDI:-]/ /g'`
	CNT="0"
	echo $DEPS | LC_COLLATE=C sort -u | while read i ; do
		if [ "${CNT}" = "0" ] ; then
			echo "${1} ${i},"
		else
			echo -n "${1}" | sed -e 's/[a-zBDI:-]/ /g'
			echo " ${i},"
		fi
		CNT=$(($CNT + 1))
	done
	if [ $1 = "Depends:" ] ; then
		echo "         \${misc:Depends},"
		echo "         \${python:Depends},"
	fi
}

calc_substitue_list () {
	if [ -r /etc/pkgos/substitute ] ; then
		while read i ; do
			SOURCE=`echo $i | cut -d" " -f1`
			DEST=`echo $i | cut -d" " -f2`
			EXP="$EXP -e s/$SOURCE/$DEST/"
		done </etc/pkgos/substitute
	fi
#	echo \'$EXP\'
}

calc_substitue_list

if [ "${1}" ] ; then
	parse_and_print ${1}
	format_output "Build-Depends:"
else
	echo "Build-Depends: debhelper (>= 9),
               dh-python,
               dh-systemd,
               openstack-pkg-tools (>= 23~),
               po-debconf,
               python-all (>= 2.6.6-3~),
               python-pbr,
               python-sphinx,"
	# Gather the dependencies.
	if [ -e test-requirements-py2.txt ] ; then
		parse_and_print test-requirements-py2.txt build-depends
	else
		parse_and_print test-requirements.txt build-depends
	fi
	DEP_LIST_TESTS=${DEP_LIST}
	parse_and_print requirements.txt
	DEP_LIST_RUNTIME=${DEP_LIST}

	# Format the output
	DEPS="${DEP_LIST_RUNTIME}\n${DEP_LIST_TESTS}"
	format_output "Build-Depends-Indep:"

	DEPS=${DEP_LIST_RUNTIME}
	format_output "Depends:"
fi
