#!/bin/bash

. debian/debian.env

# We have to be in the top level kernel source directory
if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then
	echo "This does not appear to be the kernel source directory." 1>&2
	exit 1
fi

mode=${1:?"Usage: $0 (updateconfigs|defaultconfigs|genconfigs|listnewconfigs|importconfigs)"}
yes=0
import=0
case "$mode" in
    update*configs)  mode='syncconfig' ;;
    default*configs) mode='oldconfig'; yes=1 ;;
    gen*configs)     mode='genconfigs' ;;
    listnew*configs)     mode='listnewconfig' ;;
    import*configs)     mode='syncconfig' import=1 ;;
    *) echo "$0 called with invalid mode" 1>&2
       exit 1 ;;
esac

if [ -z "$gcc" ]; then
    echo "ERROR: gcc environment variable must be set"
    exit 1
fi

kerneldir="`pwd`"
confdir="$kerneldir/${DEBIAN}/config"
variant="$2"

. $DEBIAN/etc/kernelconfig

bindir="`pwd`/${DROOT}/scripts/misc"
test -d CONFIGS || mkdir CONFIGS

if [ "$mode" = "genconfigs" ]; then
	mode="oldconfig"
fi

warning_partial=

# Use annotations to generate configs
ARCHES=$(sed -ne 's/^# ARCH: \(.*\)/\1/p' < ${confdir}/annotations)
FLAVOURS=$(sed -ne 's/^# FLAVOUR: \(.*\)/\1/p' < ${confdir}/annotations)

for flavour in ${FLAVOURS}; do
	arch=$(echo $flavour    | sed 's/\([^-]*\)-\(.*\)/\1/')
	flavour=$(echo $flavour | sed 's/\([^-]*\)-\(.*\)/\2/')
	conf_file=${arch}-config.flavour.${flavour}

	rm -rf build
	mkdir build

	# Generate .config from annotations (if a previosly generate config is
	# available use that).
	if [ -e "CONFIGS/${conf_file}" ]; then
		cat CONFIGS/${conf_file} > build/.config
	else
		python3 ${bindir}/annotations -f ${confdir}/annotations --arch ${arch} --flavour ${flavour} --export > build/.config
	fi

	# Map debian archs to kernel archs
	case "$arch" in
		ppc64|ppc64el)	kernarch="powerpc"	;;
		amd64)		kernarch="x86_64"	;;
		lpia)		kernarch="x86" 		;;
		sparc)		kernarch="sparc64"	;;
		armel|armhf)	kernarch="arm"		;;
		s390x)		kernarch="s390"		;;
		riscv64)	kernarch="riscv"	;;
		*)		kernarch="$arch"	;;
	esac

	# Determine cross toolchain to use for Kconfig compiler tests
	cross_compile="$(dpkg-architecture -qDEB_HOST_GNU_TYPE -a$arch 2>/dev/null)-"

	# Arch-specific compiler, if any
	archgcc=$(echo -e "show-%:\n\t@echo \$(\$*)\ninclude $DEBIAN/rules.d/$arch.mk" | make -s -f - show-gcc)

	# Environment variables for 'make *config'. We omit CROSS_COMPILE
	# for i386 since it is no longer supported after 19.04, however
	# we maintain the configs for hwe.
	modify_config=true
	env="ARCH=$kernarch DEB_ARCH=$arch"
	compiler_path=$(which "${cross_compile}${archgcc:-$gcc}" || true)
	if [ "$compiler_path" != '' ]; then
		env="$env CROSS_COMPILE=$cross_compile CC=$compiler_path"
	else
		echo "WARNING: ${cross_compile}gcc not installed"
		modify_config=
		warning_partial="$warning_partial $arch"
	fi

	# Call oldconfig, syncconfig or listnewconfig
	if [ "$modify_config" ]; then
		echo "* Run $mode (yes=$yes) on $arch/$flavour ..."
		if [ "$mode" = "listnewconfig" ]; then
			(make O=`pwd`/build $conc_level $env "$mode" | grep "^CONFIG_" > CONFIGS/new-${conf_file}) || true
		elif [ "$yes" -eq 1 ]; then
			yes "" | make O=`pwd`/build $conc_level $env "$mode"
		else
			make O=`pwd`/build $conc_level $env "$mode"
		fi
	fi

	# Automatically import configs back into annotations
	if [ "$import" -eq 1 ]; then
		python3 ${bindir}/annotations -f ${confdir}/annotations --arch ${arch} --flavour ${flavour} --import build/.config
	fi

	# Export config for config-check (or genconfigs)
	cat build/.config > CONFIGS/${conf_file}
done

if [ "$mode" = "listnewconfig" ]; then
	wc -l CONFIGS/new-*
	exit 0
fi

echo ""
echo "Running config-check for all configurations ..."
echo ""
fail=0
log_file=CONFIGS/config-check.log
truncate -s0 ${log_file}
for flavour in ${FLAVOURS}; do
	arch=$(echo $flavour    | sed 's/\([^-]*\)-\(.*\)/\1/')
	flavour=$(echo $flavour | sed 's/\([^-]*\)-\(.*\)/\2/')
	conf_file=${arch}-config.flavour.${flavour}

	echo "Running config-check for ${arch}-${flavour}"
	python3 ${bindir}/annotations -f ${confdir}/annotations --arch ${arch} --flavour ${flavour} --check CONFIGS/${conf_file} | tee -a ${log_file}
	[ ${PIPESTATUS[0]} -ne 0 ] && let "fail=$fail+1"
done

rc=0
if [ "$fail" != 0 ]; then
	rc=1
	echo ""
	echo "*** ERROR: $fail config-check failures detected"
	echo ""
fi

rm -rf build

if [ "$warning_partial" ]; then
	rc=1
	echo ""
	echo "WARNING: configuration operation applied only to a subset of architectures (skipped$warning_partial)" 1>&2
	echo ""
fi

exit "${rc}"
