#!/bin/sh -efu

: ${rpm_arch?} ${rpm_name?} ${rpm_filenames?} ${rpm_perms_filenames?} ${rpm_sourcerpm?}

check_python()
{
	# Check python for binary rpms only.
	[ "$package_type" = bin ] || return 0

	# python base packages are exception.
	if printf %s "$rpm_sourcerpm" |
	   grep -Eqx 'python([2-9](\.[0-9])?)?-[^-]+-[^-]+'; then
		return 0
	fi

	local f="$1" && shift || return 1
	local rc=0
	local pm_ver=
	local pm_prefix=
	local py_libdir_re='^/usr/lib(64)?/python[23]([.][0-9])?/'
	local py2_libdir_re='^/usr/lib(64)?/python2([.][0-9])?/'
	local py3_libdir_re='^/usr/lib(64)?/python3([.][0-9])?/'
	local site_packages_re="${py_libdir_re}site-packages/"
	local py2_site_packages_re="${py2_libdir_re}site-packages/"
	local py3_site_packages_re="${py3_libdir_re}site-packages/"
	local site_packages=
	local py2_site_packages=
	local py3_site_packages=
	local docs_re="$site_packages_re"'.*/docs?($|/)|^/usr/share/((gtk-)?doc|man)/'
	local is_docs=
	local bad_files

	case "$rpm_name" in
		python-module-*)
			pm_ver=2
			pm_prefix='python-module-'
			;;
		python3-module-*)
			pm_ver=3
			pm_prefix='python3-module-'
			;;
	esac

	case "$rpm_name" in
		*-doc|*-docs) is_docs=1 ;;
	esac

	if printf %s "$rpm_filenames" 2>/dev/null |
	   grep -E "$py_libdir_re" 2>/dev/null |
	   grep -Evq "$site_packages_re"; then
		FileError 'python files inside %python_libdir can be placed only in %python_sitelibdir' "$f"
		rc=1
	fi

	if [ -n "$pm_ver" ] && [ -n "$is_docs" ]; then
		bad_files="$(printf %s "$rpm_filenames" 2>/dev/null |
			     grep -Ev "$docs_re" ||
			     [ $? -eq 1 ])"
		if [ -n "$bad_files" ]; then
			bad_files="$(oneliner "$bad_files" |fmt -w 128 |head -n1)"
			FileError "python$pm_ver module docs contain unrelated files: $bad_files" "$f"
			rc=1
		fi
	fi

	# All the rest is related to python modules only.
	site_packages="$(printf %s "$rpm_filenames" |
			 grep -E "$site_packages_re" ||
			 [ $? -eq 1 ])"
	[ -n "$site_packages" ] ||
		return $rc

	py2_site_packages="$(printf %s "$site_packages" |
			     grep -E "$py2_site_packages_re" ||
			     [ $? -eq 1 ])"
	py3_site_packages="$(printf %s "$site_packages" |
			     grep -E "$py3_site_packages_re" ||
			     [ $? -eq 1 ])"

	if printf %s "$py3_site_packages" 2>/dev/null |
	   grep -Eq '^/usr/lib(64)?/python3[.][0-9]/site-packages/'; then
		FileError 'a common %python_sitelibdir must be used for python3 (i.e., minor version is not allowed)' "$f"
		rc=1
	fi

	if [ -n "$py2_site_packages" ] && [ -n "$py3_site_packages" ]; then
		FileError 'package contains both python2 and python3 modules' "$f"
		rc=1
	fi

	if [ "$pm_ver" = 2 ] || [ -n "$py2_site_packages" ]; then
		if printf %s "$rpm_requires" 2>/dev/null | cut -d' ' -f1 |
		   grep -Eqs '^(/usr/bin/)?python3'; then
			FileError "package containing python2 modules should not have python3 requirements" "$f"
			rc=1
		fi
	fi
	if [ "$pm_ver" = 3 ] || [ -n "$py3_site_packages" ]; then
		if printf %s "$rpm_requires" 2>/dev/null | cut -d' ' -f1 |
		   grep -Eqs '^(/usr/bin/)?python($|[^3])'; then
			FileError "package containing python3 modules should not have python2 requirements" "$f"
			rc=1
		fi
	fi

	local bad_dirs= noarch_pattern=
	case "$rpm_arch" in
		noarch|i?86|pentium*|athlon*)
			bad_dirs='/usr/lib64/python[23]([.][0-9])?/site-packages/' ;;
		x86_64|amd64)
			noarch_pattern='^d[^ ]+ /usr/lib/python[23]([.][0-9])?/site-packages/|^-[^ ]+ /usr/lib/python[23]([.][0-9])?/site-packages/.*\.py([co])?$'
			bad_dirs='/usr/lib/python[23]([.][0-9])?/site-packages/' ;;
	esac

	bad_files=
	if [ -n "$bad_dirs" ]; then
		bad_files="$(printf %s "$rpm_perms_filenames" |
			     grep -E "^[^ ]+ $bad_dirs" || [ $? -eq 1 ])"
	fi
	if [ -n "$bad_files" -a -n "$noarch_pattern" ]; then
		bad_files="$(printf %s "$bad_files" |
			     grep -Ev "$noarch_pattern" || [ $? -eq 1 ])"
	fi
	if [ -n "$bad_files" ]; then
		bad_files="$(printf %s "$bad_files" |cut -d' ' -f2-)"
		FileError "invalid $rpm_arch python module path: $(oneliner "$bad_files" |fmt -w 128 |head -n1)" "$f"
		rc=1
	fi

	local unknown_version_files="$site_packages_re"'[^/]*unknown-py[23][.][0-9](\.egg-info|-nspkg\.pth$)'
	local bad_version_files
	bad_version_files="$(printf %s "$site_packages" |
			     grep -E "$unknown_version_files" ||
			     [ $? -eq 1 ])"

	if [ -n "$bad_version_files" ]; then
		FileError "invalid python$pm_ver module version file(s): $(oneliner "$bad_version_files" | fmt -w 128 | head -n1)" "$f"
		rc=1
	fi

	if [ -n "$pm_ver" ]; then
		local t
		for t in "${rpm_name}-tests" "${rpm_name}-test"; do
			if printf %s "$rpm_requires" |
			   cut -d' ' -f1 |
			   grep -Fxqse "$t"; then
				FileError "python$pm_ver module depends on its test subpackage: $t" "$f"
				rc=1
			fi
		done
	fi

	return $rc
}

run_check()
{
	if ! check_python "$1"; then
		CheckError 'python modules packaging violation'
		return 1
	fi
}
