#!/bin/bash

if test -n "$KBUILD_DIR"
then
    DIR="$KBUILD_DIR"
else
    DIR="$(dirname $0)"
fi
. $DIR/../run-fstests/util/arch-funcs

KCONFIG_DIR=$DIR/kernel-configs
KBUILD=$DIR/kbuild

TYPE=config
DO_GENERIC=

set_default_arch

while [ "$1" != "" ];
do
    case "$1" in
	--perf)
	    TYPE=perf-config
	    ;;
	--blktests)
	    DO_BLKTESTS=yes
	    ;;
	--i386)
	    ARCH=i386
	    ;;
	--arm64)
	    ARCH=arm64
	    ;;
	--arch)
	    shift
	    ARCH=$1
	    ;;
	--dept)
	    DO_DEPT=yes
	    ;;
	--kasan)
	    DO_KASAN=yes
	    ;;
	--kcsan)
	    DO_KCSAN=yes
	    ;;
	--lockdep)
	    DO_LOCKDEP=yes
	    ;;
	--no-action)
	    NO_ACTION="echo"
	    ;;
	--ubsan)
	    DO_UBSAN=yes
	    ;;
	--full-debug-info|--debug-info)
	    DO_FULL_DEBUG_INFO=yes
	    ;;
	--extra-debug|debug)
	    DO_DEBUG=yes
	    ;;
	--get-config-fn)
	    DO_GET_CONFIG_FN=yes
	    ;;
	--generic)
	    DO_GENERIC=yes
	    ;;
	--help|help)
	    echo "Usage: install-kconfig [--i386] [--perf] [--blktests]" \
		 "[--extra-debug]"
	    echo "	[--kasan] [--kcsan] [--ubsan] [--lockdep]" \
		 "[--full-debug-info]"
	    echo "	[--get-config-fn] [--no-action]"
	    exit 0
	    ;;
	*)
	    echo "unknown option: $1"
	    exit 1
	    ;;
    esac
    shift
done

set_canonicalized_arch "$ARCH"
set_cross_compile

if test ! -f MAINTAINERS -o ! -f Makefile ; then
   echo "Not at top-level of kernel sources"
   exit 1
fi

BLD_DIR=$($KBUILD --get-build-dir --arch $KERN_ARCH)
mkdir -p "$BLD_DIR"

# echo "Build directory is $BLD_DIR"

KVER=$(make kernelversion)

if test -z "$KVER" ; then
    echo "Unable to determine kernel version"
    exit 1
fi

VERSION=$(echo $KVER | awk -F. '{print $1}')
SUBVERSION=$(echo $KVER | awk -F. '{print $2}' | sed -e 's/-.*//')

# echo "Kernel version is $KVER - $VERSION $SUBVERSION"

CONFIG_FN=''
while test -z "$CONFIG_FN" ; do
    fn="$KCONFIG_DIR/$KERN_ARCH-$TYPE-$VERSION.$SUBVERSION"
    if test -n "$DO_GENERIC" -o ! -f "$fn" ; then
	fn="$KCONFIG_DIR/$TYPE-$VERSION.$SUBVERSION"
    fi
    if test -f "$fn" ; then
	CONFIG_FN=$fn
	break
    fi
    if test $SUBVERSION -eq 0 ; then
	VERSION=$(($VERSION - 1))
	SUBVERSION=20
    else
	SUBVERSION=$(($SUBVERSION - 1))
    fi
    if test $VERSION = 2 ; then
	echo "Can't find configuration file?" 1>&2
	exit 1
    fi
done

if test -n "$DO_GET_CONFIG_FN" ; then
    echo "$CONFIG_FN"
    exit 0
fi

FILES=("$CONFIG_FN")

if test -f "$KCONFIG_DIR/$KERN_ARCH-config" ; then
    FILES+=("$KCONFIG_DIR/$KERN_ARCH-config")
fi

if test -n "$DO_BLKTESTS" ; then
    FILES+=("$KCONFIG_DIR/blktests-configs")
fi

if test -n "$DO_DEBUG" ; then
    FILES+=("$KCONFIG_DIR/extra-debug-configs")
fi

if test -n "$DO_FULL_DEBUG_INFO" ; then
    FILES+=("$KCONFIG_DIR/full-debug-info-configs")
fi

if test -n "$DO_DEPT" ; then
    FILES+=("$KCONFIG_DIR/dept-configs")
fi

if test -n "$DO_KASAN" ; then
    FILES+=("$KCONFIG_DIR/kasan-configs")
fi

if test -n "$DO_KCSAN" ; then
    FILES+=("$KCONFIG_DIR/kcsan-configs")
fi

if test -n "$DO_LOCKDEP" ; then
    FILES+=("$KCONFIG_DIR/lockdep-configs")
fi

if test -n "$DO_UBSAN" ; then
    FILES+=("$KCONFIG_DIR/ubsan-configs")
fi

if test -f "$BLD_DIR/.config" ; then
    $NO_ACTION mv "$BLD_DIR/.config" "$BLD_DIR/.config.bak"
fi

if test -z "$NO_ACTION" ; then
    cat "${FILES[@]}"  > "$BLD_DIR/.config"
else
    echo cat "${FILES[@]}"  \> "$BLD_DIR/.config"
fi

tags=$(awk '/^# TAG: / {printf("-%s", $3)}' "$BLD_DIR/.config")

if test -n "$tags" ; then
    base=$(awk -F\" '/CONFIG_LOCALVERSION/{print $2}' "$BLD_DIR/.config")
    echo CONFIG_LOCALVERSION=\"${base}${tags}\" >> "$BLD_DIR/.config"
fi

ARGS=("ARCH=$KERN_ARCH")

if test "$BLD_DIR" != "." ; then
    ARGS+=("O=$BLD_DIR")
fi

if grep -q CONFIG_CC_IS_CLANG=y "$BLD_DIR/.config" 2>/dev/null ; then
    ARGS+=("CC=clang")
fi

if test -n "$CROSS_COMPILE" ; then
    ARGS+=("CROSS_COMPILE=$CROSS_COMPILE")
fi

$NO_ACTION make "${ARGS[@]}" olddefconfig

exit 0
