#! /bin/sh
set -e

find()
{
    echo -n Looking for $1... >&2
    ANS=`which $2 || true`
    if [ -z "$ANS" ]; then
	if [ $# = 3 ]; then
	    echo None found\!  Giving up. >&2
	    exit 1
	fi
	echo "Not found." >&2
    elif [ -L "$ANS" ]; then
	echo -n "$ANS"... >&2
	while [ -L "$ANS" ]; do
	    LINK=`readlink $ANS`
	    case $LINK in
		/*) ANS=$LINK;;
		*) ANS=`dirname $ANS`/$LINK;;
	    esac
	done
	echo which is a link to $ANS >&2
    else
	echo Found "$ANS" >&2
    fi
    echo $ANS
}

test_net()
{
    for host; do
	echo -n . >&2
	if ifconfig | fgrep -q $host; then :;
	elif echo | telnet $host distcc 2>&1 | grep -q Connected; then
	    $GETENT hosts $host | awk '{print $2}'
	fi
    done
}

ping_network()
{
    # There are two kinds of ping (netkit ping and iputils ping)
    (ping -w1 -b $1.255 2>/dev/null; ping -c2 $1.255 2>/dev/null) | fgrep "from $1." | sed 's/.*from \([0-9.]*\):.*/\1/' | sort -u
}

scan_for_distcc()
{
    NET=`route -n | grep '^[123456789]' | awk '{print $1}' | head -1`
    case "$NET" in
	*[123456789].0)
	    echo -n scanning network $NET...
	    set +e
	    NET=`echo $NET | sed 's/\.0$//'`
	    HOSTS=`ping_network $NET`
	    DISTCC_HOSTS=`test_net $HOSTS`
	    set -e
	    echo $DISTCC_HOSTS
	    if [ -z "$DISTCC_HOSTS" ]; then
		echo no hosts found, disabling distcc.
		return 1
	    fi
	    ;;
	*)
	    echo no obvious network to scan, disabling distcc.
	    return 1
	    ;;
    esac
    return 0
}

# Let's not confuse ourselves: take ~/bin and ccontrol dirs out of path.
PATH=`echo :${PATH}: | sed -e "s,:~/bin:,," -e "s,:$HOME/bin:,," -e "s,:[^:]*ccontrol[^:]*,," | sed -e 's/^://' -e 's/:$//'`

DEST=${1:-$HOME/.ccontrol/default}

CC=`find "C compiler" cc needed`
CPLUSPLUS=`find "C++ compiler" c++ needed`
LD=`find "linker" ld needed`
MAKE=`find "make" make needed`
DISTCC=`find "distcc" distcc`
CCACHE=`find "ccache" ccache`
GETENT=`which getent || echo echo`

echo -n Counting CPUs on this machine...
PROCESSORS=`grep -cw ^processor < /proc/cpuinfo` 2>/dev/null
if [ "$PROCESSORS" -gt 0 ] 2> /dev/null; then
    echo found $PROCESSORS
else
    echo too hard, assuming 1
    PROCESSORS=1
fi

if [ -n "$DISTCC" ]; then
    echo -n Looking for distcc hosts...
    if [ -n "$DISTCC_HOSTS" ]; then
	echo $DISTCC_HOSTS
    else
	if scan_for_distcc; then :; else
	    DISTCC=""
	fi
    fi
fi

if [ "$DEST" = $HOME/.ccontrol/default ]; then
    if [ -f $HOME/.ccontrol ]; then
	echo Found old .ccontrol file, moving to .ccontrol.old
	mv -i $HOME/.ccontrol $HOME/.ccontrol.old
	if [ -f $HOME/.ccontrol ]; then
	    echo Aborting.
	    exit 1
	fi
    fi
fi
DIRNAME=`dirname "$DEST"`
if [ ! -d "$DIRNAME" ]; then
    echo Creating $DIRNAME directory
    mkdir -p "$DIRNAME"
elif [ -L "$DEST" ]; then
    rm $DEST
elif [ -f "$DEST" ]; then
    echo Moving existing "$DEST" to "$DEST".old
    mv -i "$DEST" "$DEST".old
    if [ -f $DEST ]; then
	echo Aborting.
	exit 1
    fi
fi

echo '[*]' > "$DEST"
echo "	cc = $CC" >> "$DEST"
echo "	c++ = $CPLUSPLUS" >> "$DEST"
echo "	ld = $LD" >> "$DEST"
echo "	make = $MAKE" >> "$DEST"
if [ $PROCESSORS -gt 1 ]; then
    echo "	cpus = $PROCESSORS" >> "$DEST"
fi
if [ -n "$DISTCC" ]; then
    echo "	distcc = $DISTCC" >> "$DEST"
    echo "	distcc-hosts = `echo $DISTCC_HOSTS`" >> "$DEST"
fi
if [ -n "$CCACHE" ]; then
    echo "	ccache = $CCACHE" >> "$DEST"
fi
echo
echo Created "$DEST"

if [ "$DEST" = $HOME/.ccontrol/default ]; then
    ln -s $DEST ~/.ccontrol/config
    echo Created symlink ~/.ccontrol/config
fi
