#!/bin/bash
set -e

validate_unique()
{
	[ "$#" = "2" ]
	local duplicates=$(echo $2 | tr " " "\n" | sort | uniq -d)
	if [ "$duplicates" ]; then
		echo "EE: duplicate values in $1" 1>&2
		exit 1
	fi
}

# Pick out relevant version and package information including our predecessor
# packages: linux -> linux-restricted-modules-signatures -> linux-restricted-modules
src_package=$(LC_ALL=C dpkg-parsechangelog -SSource)
src_version=$(LC_ALL=C dpkg-parsechangelog -SVersion)
src_abi=$(echo "${src_version}" | sed -ne 's/\([0-9]*\.[0-9]*\.[0-9]*\-[0-9]*\)\..*/\1/p')
src_series=$(LC_ALL=C dpkg-parsechangelog -SDistribution | sed -e 's/-\(security\|updates\|proposed\)$//')

# linux/5.8.0-41.46
src_main_package=$(echo "${src_package}" | sed -e 's/-restricted-modules//')
src_main_version=$(echo ${src_version} | sed -e 's/+[0-9][0-9\.]*$//')

# linux-restricted-generate/5.8.0-41.46[+1]
src_genr_package=$(echo "${src_package}" | sed -e 's/-restricted-modules/-restricted-generate/')
src_genr_version=${src_version}

# linux-restricted-signatures/5.8.0-41.46[+1]
src_sigs_package=$(echo "${src_package}" | sed -e 's/-restricted-modules/-restricted-signatures/')
src_sigs_version=${src_version}

# linux-restricted-modules/5.8.0-41.46[+1]

mkdir -p "debian/control.d"
: >"debian/control.interlock-up"
: >"debian/control.d/meta-nvidia"
: >"debian/control.d/nvidia"
: >"debian/control.d/migrate-nvidia"
: >"debian/control.d/transitionals-local"
: >"debian/control.d/signatures"

cat - "debian/rules.in" >"debian/rules.gen" <<EOL
#! /usr/bin/make -f

src_package := ${src_package}
src_version = ${src_version}
src_abi = ${src_abi}
src_series = ${src_series}
src_main_package = ${src_main_package}
src_main_version = ${src_main_version}
src_genr_package = ${src_genr_package}
src_genr_version = ${src_genr_version}
src_sigs_package = ${src_sigs_package}
src_sigs_version = ${src_sigs_version}

EOL

dkms_build_new=$(grep -c 'shift 7' debian/scripts/dkms-build)
if [ "$dkms_build_new" -eq 0 ]; then
	sed -i -e '/debian\/scripts\/dkms-build/s/ $(4)//' debian/rules.gen
fi

nvidia_desktop=
nvidia_server=
nvidia_ignore=
while read command arg
do
	case "$command" in
	option)		;;
	suppress)		nvidia_ignore="$nvidia_ignore $arg"; continue ;;
	*)		continue ;;
	esac

	case "$arg" in
	desktop)	nvidia_desktop=y ;;
	server)		nvidia_server=y ;;
	esac
done <"debian/package.config"

while read command flavour archs
do
	case "$command" in
	build)		;;
	*)		continue ;;
	esac

	validate_unique "archs" "$archs"
	cat - >>"debian/control.interlock-up" <<EOL
 linux-headers-${src_abi}-${flavour} (>= @VERSION@) [${archs}],
EOL

	while read package version extra
	do
		case "$package" in
		nvidia-graphics-drivers-*-server)
			[ -z "$nvidia_server" ] && continue
			;;
		nvidia-graphics-drivers-*)
			[ -z "$nvidia_desktop" ] && continue
			;;
		*) continue ;;
		esac
		case " $nvidia_ignore " in
		*\ $package\ *)		continue ;;
		esac

		case " $extra " in
		*\ signonly\ *)		continue ;;
		esac

		# If package specifies arch= keys, only build it on
		# the intersection of kernel flavour arches & the
		# package arches, otherwise build for all kernel
		# flavour arches.
		pkg_archs=
		variant=
		for cmd in $extra
		do
			case "$cmd" in
			arch=*)		pkg_archs="$pkg_archs ${cmd#arch=}" ;;
			variant=*) variant="-${cmd#variant=}" ;;
			esac
		done
		# No package arches set, build for everything
		if [ -z "$pkg_archs" ]; then
			pkg_archs=$archs
		else
			# Package arches set, build for intersection
			validate_unique "pkg_archs" "$pkg_archs"
			pkg_archs=$(sort <(echo $archs | tr " " "\n") <(echo $pkg_archs | tr " " "\n") | uniq -d | tr "\n" " ")
			# No intersection, skip
			if [ -z "$pkg_archs" ]; then
				continue
			fi
		fi

		targets=$(echo "$pkg_archs" | sed -e 's/\</nvidia-/g')
		suffix_minus=$(echo "$package$variant" | sed -e 's/nvidia-graphics-drivers-//')
		suffix_under=$(echo "$suffix_minus" | sed -e 's/-/_/g')
		suffix_short=$(echo "$suffix_minus" | sed -e 's/-server/srv/g')
		suffix_minus_common=$(echo "$package" | sed -e 's/nvidia-graphics-drivers-//')

		echo "II: build $package for $flavour $pkg_archs"

		# debian/rules.gen
		cat - >>"debian/rules.gen" <<EOL

# $package $version $suffix_minus $suffix_under
dkms_nvidia_${suffix_under}_version="$version"
nvidia_${suffix_under}_upstream_version=\$(shell echo "\$(dkms_nvidia_${suffix_under}_version)" | cut -d '-' -f 1)
gencontrol_flags += -Vdkms:nvidia-${suffix_minus}-modules="nvidia-dkms-${suffix_minus} (= \$(dkms_nvidia_${suffix_under}_version))"
gencontrol_flags += -Vnvk:nvidia-${suffix_minus}="nvidia-kernel-common-${suffix_minus_common} (>= \$(nvidia_${suffix_under}_upstream_version))"
test::
	@echo $package $version $suffix_minus $suffix_under $suffix_short $targets
$targets::
	rm -rf \$(dkms_dir)/build \$(dkms_dir)/source
	mkdir -p \$(dkms_dir)/build \$(dkms_dir)/source
EOL
		if [ "$variant" != "-open" ]; then
			cat - >>"debian/rules.gen" <<EOL
	install -d debian/linux-modules-nvidia-${suffix_minus}-\$(src_abi)-${flavour}
	install -d debian/linux-modules-nvidia-${suffix_minus}-\$(src_abi)-${flavour}/usr/lib/linux/triggers
EOL
		fi
		cat - >>"debian/rules.gen" <<EOL
	\$(call install_control,linux-modules-nvidia-${suffix_minus}-\$(src_abi)-${flavour},${flavour},nvidia,${suffix_short},postinst postrm prerm config templates)
	install -d debian/linux-objects-nvidia-${suffix_minus}-\$(src_abi)-${flavour}
	\$(call build_dkms, \$(src_abi)-${flavour}, linux-objects-nvidia-${suffix_minus}-\$(src_abi)-${flavour}, \$(CURDIR)/debian/linux-objects-nvidia-${suffix_minus}-\$(src_abi)-${flavour}/lib/modules/\$(src_abi)-${flavour}/kernel, "", nvidia-${suffix_short}, pool/restricted/n/${package}/nvidia-kernel-source-${suffix_minus}_\$(dkms_nvidia_${suffix_under}_version)_\$(arch).deb pool/restricted/n/${package}/nvidia-dkms-${suffix_minus}_\$(dkms_nvidia_${suffix_under}_version)_\$(arch).deb)
EOL

		# debian/control.d/meta-nvidia
		cat - >>"debian/control.d/meta-nvidia" <<EOL

Package: linux-modules-nvidia-${suffix_minus}-${flavour}\${variant:suffix}
Build-Profiles: <!stage1>
Architecture: ${pkg_archs}
Section: kernel
Provides: \${dkms:nvidia-${suffix_minus}-modules}, nvidia-prebuilt-kernel
Depends:
 \${misc:Depends},
 linux-modules-nvidia-${suffix_minus}-${src_abi}-${flavour} (= \${binary:Version}),
 \${nvk:nvidia-${suffix_minus}},
Description: Extra drivers for nvidia-${suffix_minus} for the ${flavour}\${variant:suffix} flavour
 Install extra signed nvidia-${suffix_minus} modules compatible with the ${flavour}\${variant:suffix} flavour.
EOL

		# debian/control.d/nvidia
		cat - >>"debian/control.d/nvidia" <<EOL

Package: linux-objects-nvidia-${suffix_minus}-${src_abi}-${flavour}
Build-Profiles: <!stage1>
Architecture: ${pkg_archs}
Section: kernel
Priority: optional
Built-Using: \${linux:BuiltUsing}
Depends:
 \${misc:Depends},
 \${shlibs:Depends},
 binutils,
Description: Linux kernel nvidia modules for version ${src_abi} (objects)
 This package contains the Linux kernel nvidia modules for version ${src_abi}.
 .
 You likely do not want to install this package directly. Instead, install the
 one of the linux-modules-nvidia-${suffix_minus}-${flavour}* meta-packages,
 which will ensure that upgrades work correctly, and that supporting packages are
 also installed.
EOL
		# debian/control.d/nvidia
		if [ "$variant" != "-open" ]; then
			cat - >>"debian/control.d/nvidia" <<EOL

Package: linux-modules-nvidia-${suffix_minus}-${src_abi}-${flavour}
Build-Profiles: <!stage1>
Architecture: ${pkg_archs}
Section: kernel
Priority: optional
Built-Using: \${linux:BuiltUsing}
Depends:
 \${misc:Depends},
 \${shlibs:Depends},
 linux-image-${src_abi}-${flavour} | linux-image-unsigned-${src_abi}-${flavour},
 linux-signatures-nvidia-${src_abi}-${flavour} (= ${src_sigs_version}),
 linux-objects-nvidia-${suffix_minus}-${src_abi}-${flavour} (= \${binary:Version}),
 \${nvk:nvidia-${suffix_minus}},
Description: Linux kernel nvidia modules for version ${src_abi}
 This package pulls together the Linux kernel nvidia modules for
 version ${src_abi} with the appropriate signatures.
 .
 You likely do not want to install this package directly. Instead, install the
 one of the linux-modules-nvidia-${suffix_minus}-${flavour}* meta-packages,
 which will ensure that upgrades work correctly, and that supporting packages are
 also installed.
EOL
		fi

		# debian/control.d/migrate-nvidia
		for cmd in $extra
		do
			case "$cmd" in
			transition=*)
				from="${cmd#transition=}"
				from_minus=$(echo "$from" | sed -e 's/nvidia-graphics-drivers-//')
				echo "II: general transition $from -> $package ($from_minus -> $suffix_minus) $pkg_archs"
				cat - >>"debian/control.d/migrate-nvidia" <<EOL

Package: linux-modules-nvidia-${from_minus}-${flavour}\${variant:suffix}
Architecture: ${pkg_archs}
Section: oldlibs
Depends: linux-modules-nvidia-${suffix_minus}-${flavour}\${variant:suffix}
Description: Extra drivers for nvidia-${from_minus} for the ${flavour} flavour (dummy transitional package)
 Transitional package for upgrades of -${from_minus} to -${suffix_minus}.
EOL
				;;
			esac
				#suffix_minus=$(echo "$package" | sed -e 's/nvidia-graphics-drivers-//')
				#suffix_under=$(echo "$suffix_minus" | sed -e 's/-/_/g')
				#suffix_short=$(echo "$suffix_minus" | sed -e 's/-server/srv/g')
		done
	done <"debian/dkms-versions"
done <"debian/package.config"

while read command from to archs
do
	case "$command" in
	transitional)	;;
	*)		continue ;;
	esac

	# debian/control.d/transitionals-local
	echo "II: manual transition linux-modules-nvidia-$from -> linux-modules-nvidia-$to $archs"
	cat - >>"debian/control.d/transitionals-local" <<EOL

Package: linux-modules-nvidia-${from}
Architecture: ${archs}
Section: oldlibs
Depends: linux-modules-nvidia-${to}
Description: Extra drivers for nvidia-${from} (dummy transitional package)
 Transitional package for upgrades of ${from} to ${to}.
EOL
done <"debian/package.config"
