#!/bin/bash
#
# --- ROCK-COPYRIGHT-NOTE-BEGIN ---
# 
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
# Please add additional copyright information _after_ the line containing
# the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
# the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
# 
# ROCK Linux: rock-src/scripts/Config
# ROCK Linux is Copyright (C) 1998 - 2006 Clifford Wolf
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. A copy of the GNU General Public
# License can be found at Documentation/COPYING.
# 
# Many people helped and are helping developing ROCK Linux. Please
# have a look at http://www.rocklinux.org/ and the Documentation/TEAM
# file for details.
# 
# --- ROCK-COPYRIGHT-NOTE-END ---

if [ -z "${lines:=$LINES}" -o -z "${columns:=$COLUMNS}" ] ; then
	if [ "$( type -p stty )" ] ; then
		lines="$(   stty size 2> /dev/null | cut -d' ' -f1 )"
		columns="$( stty size 2> /dev/null | cut -d' ' -f2  )"
	fi
	[ -z "$lines"   -o "$lines"   -le 0 ] 2> /dev/null && lines=24
	[ -z "$columns" -o "$columns" -le 0 ] 2> /dev/null && columns=80
fi

eval "$(egrep '^rockver=' scripts/parse-config)"

config=default
do_config_cycle=0
delete_mode=0
oldconfig=''
nobashmod=''
profile=""

while [ "$1" ] ; do
        case "$1" in
	    -cycle)	do_config_cycle=1 ; shift ;;
	    -delete)	delete_mode=1     ; shift ;;
	    -profile)	profile='-profile'        ; shift ;;
	    -oldconfig)	oldconfig='-oldconfig'    ; shift ;;
	    -nobashmod)	nobashmod='-nobashmod'    ; shift ;;
	    -cfg)	config="$2"       ; shift ; shift ;;

	    *)
		echo
		echo "Usage: $0 [ -delete | -oldconfig ] [ -cfg <config> ]"
		echo " Create and modify build configurations for the other"
		echo " scripts, e.g. Download, Build-Target, and Emerge-Pkg."
		echo
		echo "	-cfg <config>	use <config> as the configuration name. If this option"
		echo "			is not set the name 'default' is used. If no"
		echo "			configuration by this name exists, one with default"
		echo "			settings is created."
		echo "	-delete		delete the specified configuration"
		echo "	-oldconfig	run without a menu-based interface; changes to settings"
		echo "			in configuration files have to be made manually before"
		echo "			./scripts/Config recreates the whole configuration"
		echo  
		echo "Other options:"
		echo "	-profile	create a config.profile with profiling data"
		echo "	-nobashmod	don't use the bash config helper plugin"
		echo
		exit 1 ;;
        esac
done

./scripts/Check-System || exit 1

if [ $delete_mode = 1 ] ; then
	rm -rv config/$config
	exit $?
fi

# hook for third-party targets that need to insert additional packages before config runs, for example.
for precnf in target/*/preconfig.sh ; do
	[ -f $precnf ] && . $precnf 
done

if [ $do_config_cycle = 0 ]
then
	export swpid=swp$$
	rm -f config.data.$swpid config.dialog.$swpid config.out.$swpid config.help.$swpid
	rm -f config.pcache.data.$swpid config.pcache.cmd.$swpid
	rm -f rockdialog.scrltmp # src/rockdialog.bin
	mkdir -p src

	if [ -z "$oldconfig" -a ! -f src/rockdialog.bin ] ; then
		echo "Creating rockdialog tool."
		command="gcc misc/rockdialog/*.c `
			`-Imisc/rockdialog -lncurses -o src/rockdialog.bin"
		echo "$command" ; eval "$command.$swpid"
		mv src/rockdialog.bin.$swpid src/rockdialog.bin
	fi

	echo "Creating configuration script."
	cat << EOT > src/rockconfig.awk.$swpid
#!/usr/bin/awk -f

FNR == 1 {
        if ( lastfile ) {
                print "### END of " lastfile;
        }
        print "### BEGIN of " FILENAME;
        lastfile = FILENAME;
}

END {
        print "### END of " FILENAME;
}

\$1 == "%include" {
        \$1 = "awk -f src/rockconfig.awk";
        system(\$0);
        next;
}

\$1 == "#" { next; }
{ print; }
EOT
	mv src/rockconfig.awk.$swpid src/rockconfig.awk
	awk -f src/rockconfig.awk scripts/config.in > src/rockconfig.in.$swpid 2> /dev/null
	mv src/rockconfig.in.$swpid src/rockconfig.in

	echo "Running ROCK Linux $rockver configuration ..."
	while "$0" -cfg $config $oldconfig $profile $nobashmod -cycle ; do : ; done

	exit 0
fi

if [ -z "$nobashmod" ]; then
	if [ ! -f src/config_helper.so -o misc/tools-source/config_helper.c -nt src/config_helper.so ]; then
		echo "Building src/config_helper.so."
		gcc -shared -fPIC -Wall -o src/config_helper.so misc/tools-source/config_helper.c || exit 1
	fi
	enable -f src/config_helper.so cfghlp || exit 1
fi

if [ -z "$profile" ]; then
	bprof() { :; }
	bprof_print() { :; }
else
	if [ ! -f src/bash_profiler.so -o misc/tools-source/bash_profiler.c -nt src/bash_profiler.so ]; then
		echo "Building src/bash_profiler.so."
		gcc -shared -fPIC -Wall -o src/bash_profiler.so misc/tools-source/bash_profiler.c || exit 1
	fi
	enable -f src/bash_profiler.so bprof || exit 1
	bprof_print() {
		bprof all print >> config.profile
		awk '
			$4 == "profiled" { next; }
			$4 != "main" { count["profiled"]+=$1; time["profiled"]+=$2; }
			{ count[$4]+=$1; time[$4]+=$2; }
			END {
				for (id in count)
					printf "%7d %7Ld %10.3f %s\n", count[id], time[id], time[id]/count[id], id;
			}
		' < config.profile | sort -n -k2 > config.profile.new
		mv config.profile.new config.profile
	}
fi

bprof main start

. scripts/config.func

arch=none
if expr "`uname -m`" : "x86_64"  > /dev/null ; then arch=x86     ; fi
if expr "`uname -m`" : "i.86"    > /dev/null ; then arch=x86     ; fi
if expr "`uname -m`" : "alpha"   > /dev/null ; then arch=alpha   ; fi
if expr "`uname -m`" : "ppc"     > /dev/null ; then arch=powerpc ; fi
if expr "`uname -m`" : "powerpc" > /dev/null ; then arch=powerpc ; fi
if expr "`uname -m`" : "sparc"   > /dev/null ; then arch=sparc   ; fi
if expr "`uname -m`" : "mips"    > /dev/null ; then arch=mips    ; fi
current="" ; export ROCKCFG_ARCH="$arch" ; export ROCKCFG_EXPERT=0
menu_this=0 ; menu_current=0 ; menu_counter=0
menu_stack=x ; menu_back=-1 ; menu_backpos=-1

mkdir -p config/$config
touch config/$config/config
touch config/$config/packages

rm -rf config/$config.$swpid
cp -r config/$config config/$config.$swpid

configtitle="$(printf ' %-50s %6s active packages ]' \
	"ROCK Linux $rockver Configuration - $config" \
	"[ $(echo `grep '^X' config/$config/packages | wc -l`)" )"

bprof main stop
. ./config/$config.$swpid/config
if [ -f config/$config.$swpid/config_usr ]; then
	nousrconfig=0
	. ./config/$config.$swpid/config_usr
else
	nousrconfig=1
fi
bprof main start

rm -f config.dialog.$swpid config.data.$swpid config.help.$swpid
touch config.dialog.$swpid config.data.$swpid config.help.$swpid
echo -e "#\n# ROCK Linux $rockver Config File\n#" > config/$config.$swpid/config
echo -e "#\n# ROCK Linux $rockver User Config File\n#" > config/$config.$swpid/config_usr
spacer="" ; expert=0 ; tabspace="5" ; tabspace_list=""
commentnr=0 ; editfilenr=0

bprof mkpkglist start
cmd="./scripts/Create-PkgList"
[ "$ROCKCFG_DISABLE_BROKEN" = 1 ] && cmd="$cmd -nobroken"
cmd="$cmd $ROCKCFG_ARCH"

if [ "$cmd" != "`cat config.pcache.cmd.$swpid 2> /dev/null`" ] ; then
	eval "$cmd" | tee config.pcache.data.$swpid > config/$config.$swpid/packages
	echo "$cmd" > config.pcache.cmd.$swpid
else
	cat config.pcache.data.$swpid > config/$config.$swpid/packages
fi
bprof mkpkglist stop

export ROCKCFG_ID="$rockver"; pkgin; . src/rockconfig.in; pkgout
echo "export ROCKCFG_ID='$ROCKCFG_ID'" >> config/$config.$swpid/config
rm -f config/$config.$swpid/*.tmp

sort -k3 config/$config.$swpid/packages > config/$config.$swpid/packages.sorted
mv -f config/$config.$swpid/packages.sorted config/$config.$swpid/packages

cut -f1,2,4,5,8- -d' ' config/$config.$swpid/packages | sed 's, [^ ]*$,,' | \
tr ' ' '\t' | expand -t2,15,35, > config/$config.$swpid/packages.txt

for x in ${!ROCKCFGUSR_*}; do
	eval "echo \"$x='\$$x'\""
done >> config/$config.$swpid/config_usr

configtitle="$(printf ' %-50s %6s active packages ]' \
	"ROCK Linux $rockver Configuration - $config" \
	"[ $(echo `grep '^X' config/$config.$swpid/packages | wc -l`)" )"

bprof main stop

if [ -z "$oldconfig" ] ; then
    eval "./src/rockdialog.bin --title 'Build Config' \
	--backtitle '$configtitle' \
	--menu 'Arrow keys navigate the menu.  Press <Enter> to activate menu items.  Highlighted letters are hotkeys.' \
	$(( $lines - 4 )) $(( $columns - 5 )) $(( $lines - 12 )) \
	'$current' `tr '\n' ' ' < config.dialog.$swpid`" 2> config.out.$swpid
    returncode=$? ; item="`cat config.out.$swpid`"
else
    returncode=1
fi

bprof main start

[ "$returncode" = 1 -a "$menu_back" -ne -1 ] && returncode="menu-back"

writeback() {
	for x in $( ls config/$config.$swpid ); do
		cp config/$config.$swpid/$x config/$config.$swpid/__tmp
		mv config/$config.$swpid/__tmp config/$config/$x
	done
	for x in $( ls config/$config ); do
		[ -e config/$config.$swpid/$x ] || rm -f config/$config/$x
	done
	rm -rf config/$config.$swpid
}

case "$returncode" in
	0|6)
		command="`grep "^$item	" config.data.$swpid | cut -f2-`"
		{ echo -e "\n# Remember menu position:\ncurrent='$item'"
		echo -e "\n# Remember sub-menu:\nmenu_current='$menu_current'"
		echo -e "\n# Execute this config command:\n$command"
		} >> config/$config.$swpid/config_usr
		;;
	menu-back)
		{ echo -e "\n# New menu position:\ncurrent='$menu_backpos'"
		echo -e "\n# New sub-menu:\nmenu_current='$menu_back'"
		} >> config/$config.$swpid/config_usr
		;;
	1|255)
		rm -f config.data.$swpid config.dialog.$swpid config.out.$swpid config.help.$swpid
		rm -f config.pcache.data.$swpid config.pcache.cmd.$swpid
		rm -f rockdialog.scrltmp # src/rockdialog.bin
		echo "New config written to config/$config/*."
		echo "Cleaning up. Configuration finished."
		writeback
		bprof main stop
		bprof_print
		exit 1 ;;
	2)
		tempitem=$item
		item=$(echo $item | cut -f1 -d' ')  # dialog(1) bug?
		{ echo -e "\n# Remember menu position:\ncurrent='$item'"
		echo -e "\n# Remember sub-menu:\nmenu_current='$menu_current'"
		} >> config/$config.$swpid/config_usr

		get_help $item > config.dialog.$swpid

		bprof main stop
		./src/rockdialog.bin --title 'ROCK Linux Config - Help' \
			--backtitle "ROCK Linux $rockver Configuration" \
			--textbox config.dialog.$swpid \
			$(( $lines - 4 )) $(( $columns - 5 ))
		bprof main start
		;;
	*)
		echo "unknown returncode: $returncode"
		writeback	
		bprof main stop
		bprof_print
		exit 1 ;;
esac

writeback	

bprof main stop
bprof_print

exit 0