#!/bin/sh
PATH=/ldcg/bin:${PATH}
LD_LIBRARY_PATH=/ldcg/lib:${LD_LIBRARY_PATH}
export PATH LD_LIBRARY_PATH

#------------------------------------------------------------------------
# Establish default values
#------------------------------------------------------------------------
inlining="--enable-inlining"
optimization="--with-optimization=high"
#------------------------------------------------------------------------
# Common subroutines
#------------------------------------------------------------------------
which()
{
    for dir in `echo $PATH | sed -e 's/:$/ ./' -e 's/^:/. /' -e 's/::/ . /g' -e 's/:/ /'`
    do
      if test -x $dir/$1
      then
	  echo $dir/$1
	  return 0;
      fi
    done
    echo "$1: Command not found."
    return 1;
}
#------------------------------------------------------------------------
# These are the general routines to be invoked. They start from the
#   source dir and return there when they have completed their task
#------------------------------------------------------------------------

cd_builddir()
{
    cd "${builddir}"
}

cd_sourcedir()
{
    until test -f build-ldas
    do
	cd ..
	if test "`pwd`" = "/"
	then
	    #------------------------------------------------------------
	    # Exiting because unable to find the source directory
	    #------------------------------------------------------------
	    exit 1
	fi
    done
}

eval_make_target()
{
    if test -f Makefile;
    then
	#----------------------------------------------------------------
	# There is actually a Makefile so there should be rules
	#----------------------------------------------------------------
	make ${make_opt} $1;
    fi > build_logs/make_$1 2>&1
    
}

is_vcs( )
{
    cd_sourcedir
    if test -d CVS
    then
	echo "yes"
    else
	echo "no"
    fi
}

do_configure()
{
    case "${nostow}" in
    yes)
	stow_pkgs_dir=""
	ldas_pkg_dir=""
	;;
    *)
	stow_pkgs_dir="/stow_pkgs"
	ldas_pkg_dir="/ldas-${mmp_version}"
	;;
    esac
    install_dir="${prefix}${stow_pkgs_dir}${ldas_pkg_dir}";
    #--------------------------------------------------------------------
    # Configure the system
    #--------------------------------------------------------------------
    cd_builddir
    case "`uname`" in
    SunOS)
	#----------------------------------------------------------------
	# Use DB2 interface for SunOS
	#----------------------------------------------------------------
	eval ../configure --prefix=${install_dir} \
	    ${std_configure_opts} \
	    $config_opts
	;;
    Linux)
	#----------------------------------------------------------------
	# Use IODBC interface for Linux
	#----------------------------------------------------------------
	eval ../configure --prefix=${install_dir} \
	    ${std_configure_opts} \
	    $config_opts
	;;
    *)
	#----------------------------------------------------------------
	# Rely on configure to handle all other cases.
	#----------------------------------------------------------------
	echo "WARNING: Building for unsupported platform (`uname`)" > /dev/tty
	echo "	This build may not succeed." > /dev/tty
	../configure --prefix=${prefix} \
	    ${std_configure_opts} \
	    ${config_opts}
    esac > build_logs/config 2>&1
    res=$?;
    cd_sourcedir;
    return $res;
}

do_cvs_update()
{
    #--------------------------------------------------------------------
    # Check to see if the source code is to be updated with CVS
    #--------------------------------------------------------------------
    if test "xtrue" = "x${update}"
    then
	#----------------------------------------------------------------
	# Yes it is.
	#----------------------------------------------------------------
	cvs update -d > ${builddir}/build_logs/update 2>&1
    fi
}

do_cleanup()
{
    #--------------------------------------------------------------------
    # Cleanup from a previous build
    #--------------------------------------------------------------------
    vcs="`is_vcs`"
    cd_builddir
    case $vcs in
    yes)
    	eval_make_target distclean
	;;
    *)
    	eval_make_target clean
	;;
    esac
    cd_sourcedir
}

do_dist()
{
    #--------------------------------------------------------------------
    # Create a distribution of the system
    #--------------------------------------------------------------------
    cd_builddir
    eval_make_target dist
    cd_sourcedir
}

do_distcheck()
{
    #--------------------------------------------------------------------
    # Create a distribution of the system
    #--------------------------------------------------------------------
    cd_sourcedir
    vcs="`is_vcs`"
    cd_builddir
    case $vcs in
    yes)
	#----------------------------------------------------------------
	# This is a VCS version
	#----------------------------------------------------------------
	eval_make_target distcheck-ldas
	;;
    *)
	#----------------------------------------------------------------
	# This is a tarball version
	#----------------------------------------------------------------
        if test -f Makefile;
        then
	    #------------------------------------------------------------
	    # There is actually a Makefile so there should be rules
	    #------------------------------------------------------------
	    make ${make_opt} check;
	fi > build_logs/make_distcheck-ldas 2>&1
	;;
    esac
    cd_sourcedir
}

do_install()
{
    if test x${inst} = xyes
    then
        #----------------------------------------------------------------
        # installation of the system
        #----------------------------------------------------------------
	case "${nostow}" in
	yes)
	    stow_pkgs_dir=""
	    ldas_pkg_dir=""
	    ;;
	*)
	    stow_pkgs_dir="/stow_pkgs"
	    ldas_pkg_dir="/ldas-${mmp_version}"
	    ;;
	esac
        cd_builddir
	mkdir -p ${prefix}${stow_pkgs_dir}
        if test -w ${prefix}${stow_pkgs_dir}
        then
	    #------------------------------------------------------------
	    # have the correct priviledges to put the files in the
	    #   destination directory.
	    #------------------------------------------------------------
	    # remove -j option
	    make_install_opts=`echo ${make_opt}  |  sed 's/-j[ \t]*[2-9]*[ \t]*//'`
	    make ${make_install_opts} prefix=${prefix}${stow_pkgs_dir}${ldas_pkg_dir} install > build_logs/install 2>&1
	else
	    echo "WARNING: $USER does not have write permission for ${prefix}${stow_pkgs_dir}" 2>&1
        fi
        cd_sourcedir
    fi
}

do_make()
{
    #--------------------------------------------------------------------
    # actually build the system
    #--------------------------------------------------------------------
    cd_builddir
    make ${make_opt} > build_logs/make 2>&1
    res=$?
    cd_sourcedir
    return $res
}

do_make_check()
{
    if test x${make_check} = xyes
    then
	#----------------------------------------------------------------
	# actually build the system
	#----------------------------------------------------------------
	cd_builddir
	opts=`echo " ${make_opt}" | sed -e 's/-k//g'`
	make -k ${opts} check > build_logs/make_check 2>&1
	res=$?
	cd_sourcedir
	return $res
    fi
}

do_prep()
{
    #--------------------------------------------------------------------
    # search of gcc
    #--------------------------------------------------------------------
    case "`gcc --version | head -n 1 | sed 's/^.*[ ][ ]*\([0-9][0-9]*\.[0-9.][0-9.]*\)\([ ][ ]*.*\)*$/\1/'`" in
    2.95.*)
	;;
    3.0.3|3.0.4)
	;;
    3.2|3.2.*|3.3|3.3.1|3.3.3|3.3.5|3.3.6)
	;;
    4.0.3)
	;;
    4.1.1|4.1.2)
	;;
    *)
	case $warn_unsupported_compiler in
	0)
	  echo "unable to find a usable version of gcc" >&2
	  which gcc >&2
	  gcc --version >&2
	  gcc --version| grep gcc | sed -e 's/^[^0-9][^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/g' >&2
          rm ${builddir}/build.lock
	  exit 1
	  ;;
	1)
	 echo "*** Warning: the version of GCC being used for compilation ***"
	 echo "***    has not been certified.                             ***"
	 which gcc >&2
	 gcc --version >&2
	 gcc --version| grep gcc | sed -e 's/^[^0-9][^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/g' >&2
	 echo "***  Proceed at your own risk                              ***"
	 ;;
	esac
    esac
    #--------------------------------------------------------------------
    # ensure certain environment variables are set
    #--------------------------------------------------------------------
    if test -z "$USER"
    then
	USER=`ps -f | grep -v UID | sed -e 's/^[ 	]*\([^ 	]*\)[ 	].*$/\1/g' | uniq`
    fi
    if test -z "$mail_addr"
    then
	mail_addr=$USER
    fi
    #--------------------------------------------------------------------
    # get ready to do a new build
    #--------------------------------------------------------------------
    case "${config_opts}" in
    *--with*-ilwd*) ;;
    *) std_configure_opts="${std_configure_opts} --with-ilwd";;
    esac
    case "${config_opts}" in
    *--with*-ospace*) ;;
    *) std_configure_opts="${std_configure_opts} --with-ospace=/ldcg";;
    esac
    case "${config_opts}" in
    *--without-odbc-dm)
	;;
    *--with-odbc-dm=*)
	;;
    *)
	case "`uname`" in
	SunOS)
	    std_configure_opts="${std_configure_opts} --with-odbc-dm=DB2"
	    ;;
	Linux)
	    if test -d /ldcg/IBMdb2/include
	    then
		std_configure_opts="${std_configure_opts} --with-odbc-dm=DB2"
	    else
		std_configure_opts="${std_configure_opts} --with-odbc-dm=IODBC"
	    fi
	    ;;
	esac
	;;
    esac
    case "${config_opts}" in
    *--with*-odbc-include*)
	;;
    *)
	case "`uname`" in
	SunOS)
	    std_configure_opts="${std_configure_opts} --with-odbc-include=${inc}"
	    ;;
	Linux)
	    case "${config_opts}" in
	    *--with-odbc-dm=DB2*)
		std_configure_opts="${std_configure_opts} --with-odbc-include=${inc}"
		;;
	    esac
	    ;;
	esac
	;;
    esac
    case "${config_opts}" in
    *--with*-odbc-libraries*)
	;;
    *)
	case "`uname`" in
	SunOS)
	    std_configure_opts="${std_configure_opts} --with-odbc-libraries=${lib}"
	    ;;
	Linux)
	    case "${config_opts}" in
	    *--with-odbc-dm=DB2*)
		std_configure_opts="${std_configure_opts} --with-odbc-libraries=${lib}"
		;;
	    esac
	    ;;
	esac
	;;
    esac
    case "${config_opts}" in
    *--*able-static*)
	;;
    *)
	std_configure_opts="${std_configure_opts} --disable-static"
	;;
    esac
    case "${config_opts}" in
    *--enable-64bit*)
        if test -d /ldcg/lib64/.
        then
            PATH="/ldcg/bin64:/ldcg/sbin64:${PATH}"
            LD_LIBRARY_PATH="/ldcg/lib64:${LD_LIBRARY_PATH}"
	    export PATH LD_LIBRARY_PATH
        fi
        if test -d /ldcg/lib/64/.
        then
            PATH="/ldcg/bin/64:/ldcg/sbin/64:${PATH}"
            LD_LIBRARY_PATH="/ldcg/lib/64:${LD_LIBRARY_PATH}"
	    export PATH LD_LIBRARY_PATH
        fi
	;;
    esac


    #--------------------------------------------------------------------
    # Obtain the version number in from the configuration file
    #--------------------------------------------------------------------
    mmp_version="`grep AC_INIT configure.in | sed -e 's/^.*,[ \t]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ \t]*,.*)$/\1/'`"
    export mmp_version ;
    if test -z "${prefix}"
    then
	prefix="/ldas"
    fi
}

do_start()
{
    #--------------------------------------------------------------------
    # prepare the system by making sure configure and other files
    #   exist.
    #--------------------------------------------------------------------
    if true
    then
	echo doing autoreconf;
	autoreconf --install;
    fi > ${builddir}/build_logs/autoreconf 2>&1
}

sendmail()
{
    if test -x /usr/ucb/mail
    then
	/usr/ucb/mail -s "build-ldas warnings and errors" $1 < $2
    elif mail --help 2>&1 | grep '\[-s subject\]' > /dev/null 2>&1
    then
        mail -s "build-ldas warnings and errors" $1 < $2
    else
	mail $1 < $2
    fi
}

show_errors()
{
    cd_builddir
    if test -d build_logs
    then
	cd build_logs
	case "$1" in
	-errors-make)
	    for f in make make_distcheck-ldas
	    {
	        if test -f $f
	        then
	            fileset="$fileset $f"
	        fi
	    }
	    ;;
	*) fileset='*';;
	esac
	case "x$fileset" in
	x)
	    echo "No files found" 1>&2
	    exit 1
	    ;;
	esac
	egrep ${GREP_FLAGS} '([^\*]\*\*\*[^\*]|(^(-- )*FAIL))' $fileset /dev/null
    else
        echo Unable to find the directory build_logs
    fi
    cd_sourcedir
}

show_warnings()
{
    cd_builddir
    if test -d build_logs
    then
	cd build_logs
	case "$1" in
	-warnings-make)
	    for f in make make_distcheck-ldas
	    {
	        if test -f $f
	        then
	            fileset="$fileset $f"
	        fi
	    }
	    ;;
	*) fileset='*';;
	esac
	case "x$fileset" in
	x)
	    echo "No files found" 1>&2
	    exit 1
	    ;;
	esac
	grep -v 'warning: remember to run' $fileset /dev/null | \
	egrep -v 'libtool: link: warning: .* moved\.?$' | \
	egrep -v 'install: warning: relinking ' | \
	egrep -v 'SWIG_.*' | \
	egrep -v 'warning: `.*yy_' | \
	grep ${GREP_FLAGS} -i 'warning:'
    else
	echo Unable to find the directory build_logs
    fi
    cd_sourcedir
}

sys_config()
{
    #--------------------------------------------------------------------
    # Determine if grep handles -B option
    #--------------------------------------------------------------------
    grep -B 3 nothing < /dev/null > /dev/null 2>&1
    case $? in
    0|1) GREP_FLAGS="${GREP_FLAGS} -B 3";;	# YES!!!
    *) ;;					# NO :(
    esac
}

usage()
{
    echo "Usage: ${prog} [OPTION] ..."
    echo " "
    echo "Build all or part of the LDAS system."
    echo " "
    echo "  -builddir[=DIR]    Specify the directory in which to build"
    echo "  -check             Do a \"make check\" after building code"
    echo "  -config-only       Do all steps up to and including configuration"
    echo "  -force             Don't stop make on errors"
    echo "  -help              Print list of options and then exits"
    echo "  -install           Perform the installation step"
    echo "  -no-stow           Don't use stow's installation paradigm"
    echo "  -mail[=ADDR]       Mail warning messages and error messages"
    echo "  -parallel[=NUM]    Make use of parallel make. If NUM is specified,"
    echo "                        then only spawn NUM subprocess, else spawn"
    echo "                        as many as possible"
    echo "  -tmpdir[=DIR]      Specify the location of temporary files. The"
    echo "                        default value is the current directory."
    echo " "
    echo "  Commands to give status of the LDAS build"
    echo " "
    echo "  -errors            Display known error messages in all log files"
    echo "  -errors-make       Display known error messages in make log file"
    echo "  -status            Display build process currently executing"
    echo "                        along with directory listing of log"
    echo "                        files sorted by time last modified"
    echo "  -warnings          Display known warning message in all log files"
    echo "  -warnings-make     Display known warning messages in make log file"
    echo " "
    echo "  Options inteded for LDAS developers"
    echo " "
    echo "  -dist              Make a tar ball distribution"
    echo "  -distcheck         Make a tar ball distribution and try compiling"
    echo "  -update            Perform a CVS update before building. This"
    echo "                        option should not be used with tar ball"
    echo "                        distributions"
    echo "  -warn-unsupported-compiler"
    echo "                     Only display a warning message if the compiler"
    echo "                     if the compiler is unsupported"
    echo " "
    echo "  Configure options which may be passed to ${prog}"
    echo " "
    echo "  --prefix=PREFIX        install architecture-independent files in"
    echo "                         PREFIX [/ldas]"
    echo "  --with-extra-cxxflags  Additional C++ compiler flags"
    echo "  --with-extra-ldflags   Additional linker flags"
    echo "  --with-ldflags         Replace linker flags"
    echo "  --with-ldas-target=[production|developement|system_test]"
    echo "                         Create target specific LDAS resource file"
    echo "  --with-mountpt         Specify frame builder directory"
    echo "  --with-optimization=[extreme|high|medium|low|none]"
    echo "                         Compiler optimization"
    echo "  --disable-inlining     Disable inlining of functions"
    echo "  --enable-64bit         Enable 64-bit binaries generation[default=no]"
    echo "  --with-ospace[=DIR]    ObjectSpace directory"
    echo "  --with-fftw3[=DIR]     FFTW 3.x directory"
    echo "  --without-threads      Don't build reentrant code"
    echo "  --enable-metadata-api=no"
    echo "                         Don't build metadata API"
    exit $1
}

# Build directory name
builddir="`uname`-`uname -m`"
builddir="`echo $builddir | sed -e 's,/,_,g'`"
case "`uname -n`" in
*test*) builddir="${builddir}-test";;
esac

#------------------------------------------------------------------------
# find out what tasks are to be performed.
#------------------------------------------------------------------------
prog="`basename $0`"
action_seq=""
remove_logs=0;
warn_unsupported_compiler=0;
sys_config
for ac_option
do
    case "$ac_option" in
    -remove-logs)
	remove_logs=1;
	continue;
	;;
    *)
	param_list="$param_list '$ac_option'"
	;;
    esac
    case "$ac_option" in
    -builddir)
	builddir="`uname`-`uname -m`"
	;;
    -builddir=*)
	builddir="`echo ${ac_option} | sed -e 's/-builddir=//'`"
	;;
    -check) make_check="yes"; ;;
    -config-only) config_only="true"; ;;
    -dist)
	action_seq="do_dist"
	if test ! -f Makefile.in
	then
    		action_seq="do_start do_configure ${action_seq}"
		continue
	fi
	if test ! -f ${builddir}/Makefile
	then
    		action_seq="do_configure ${action_seq}"
	fi
	;;
    -distcheck)
	action_seq="do_distcheck"
        if test ! -f Makefile.in
        then
                action_seq="do_start do_configure ${action_seq}"
                continue
        fi
        if test ! -f ${builddir}/Makefile
        then
                action_seq="do_configure ${action_seq}"
        fi
	;;
    -compiler-set=*)
	case "`echo ${ac_option} | sed -e 's/-[^=]*=//'`" in
	SunPro)
	    CC=cc
	    CXX=CC
	    export CC
	    export CXX
	    builddir="${builddir}-SunPro";
	    ;;
	esac
	;;
    -errors*) errors="${ac_option}"	;;
    -force) make_opt="${make_opt} -k"; ;;
    -help|--help) usage 0 ;;
    -mail) options="${options} mail "; ;;
    -mail=*)
	options="${options} mail "
	mail_addr="`echo ${ac_option} | sed -e 's/-mail=//'`"
	;;
    -no-setup) options="${options} no_setup"; ;;
    -nohup) option="nohup"; echo nohup;;
    -install) inst="yes"; ;;
    -no-stow|-nostow) nostow="yes"; ;;
    -parallel) make_opt="${make_opt} -j"; ;;
    -parallel=*)
	make_opt="${make_opt} -j `echo ${ac_option} | sed -e 's/-parallel=//'`"
	
	;;
    -status) status="true"; ;;
    -tmpdir)
	TMPDIR="."
	export TMPDIR
	
	;;
    -tmpdir=*)
	TMPDIR="`echo ${ac_option} | sed -e 's/--tmpdir=//'`"
	export TMPDIR
	
	;;
    -update) update="true"; ;;
    -warn-unsupported-compiler)
        warn_unsupported_compiler=1;
	;;
    -warnings*) warnings="${ac_option}" ;;
    --*able-inlining) inlining="${ac_option}" ;;
    --without-optimization) optimization="${ac_option}" ;;
    --with-optimization=*) optimization="${ac_option}" ;;
    --prefix=*)
	prefix="`echo ${ac_option} | sed -e 's/--prefix=//'`"
	
	;;
    --*)
	config_opts="${config_opts} '$ac_option'"
	
	;;
    -*)
	echo "ERROR: Unsupported option: ${ac_option}"
	usage 1
	
	exit 1
	;;
    *) cd ${ac_option}; ;;
    esac
done

#------------------------------------------------------------------------
# Add back to the configuration options values that have defaults
#------------------------------------------------------------------------

config_opts="${config_opts} $inlining $optimization"

#------------------------------------------------------------------------
# Create the build directory
#------------------------------------------------------------------------

if test ! -d "${builddir}"; then mkdir "${builddir}"; fi

#------------------------------------------------------------------------
# Do some checks on the latest build
#------------------------------------------------------------------------

if test "xtrue" = "x${status}"
then
    cd_builddir
    echo Checking status ...
    test -f build.lock && ps -aef | grep `cat build.lock`
    ls -lrt build_logs
    exit 0
fi
if test -n "${warnings}"
then
    show_warnings ${warnings}
    exit 0
fi
if test -n "${errors}"
then
    show_errors ${errors}
    exit 0
fi
#------------------------------------------------------------------------
# check to see if a build is happening
#------------------------------------------------------------------------
cd_builddir
if test -f build.lock && kill -0 `cat build.lock` > /dev/null 2>&1
then
    exit 1
fi
mkdir -p build_logs > /dev/null 2>&1
#------------------------------------------------------------------------
# Go to the source directory
#------------------------------------------------------------------------
cd_sourcedir

if test "$option" = "nohup"
then
    echo $$ > ${builddir}/build.lock
    uname -a > ${builddir}/host
    do_prep
    do_cvs_update
    if test -z "${action_seq}"
    then
	case "$options" in
	*\ no_setup\ *) ;;
	*)
	    action_seq="do_cleanup do_start";;
	esac
	action_seq="${action_seq} do_configure"
	if test "${config_only}" != "true"
	then
            action_seq="${action_seq} do_make do_make_check do_install"
	fi
    fi

    exit_status="0"
    for action in ${action_seq}
    do
	if test $exit_status = 0
	then
	    eval $action
	    exit_status="$?";
	    if test $exit_status != 0
	    then
		echo $action action failed;
	    fi
	fi
    done

    case "$options" in
    *\ mail\ *)
	if test -n "$mail_addr"
	then
	    mf=${builddir}/mail.${USER}
	    cat ${builddir}/host > ${mf}
	    echo " " >> ${mf}
	    echo "==================================================" >> ${mf}
	    echo "ERROR Messages:" >> ${mf}
	    echo "==================================================" >> ${mf}
	    echo " " >> ${mf}
	    show_errors -errors >> ${mf}
	    echo " "  >> ${mf}
	    echo "==================================================" >> ${mf}
	    echo "WARNING Messages:" >> ${mf}
	    echo "==================================================" >> ${mf}
	    echo " " >> ${mf}
	    show_warnings -warnings >> ${mf}
            sendmail ${mail_addr} ${mf}
	    rm ${mf}
	fi
	;;
    esac
    rm ${builddir}/build.lock
    exit $exit_status
else
    if test x$remove_logs = "x1"
    then
	rm -rf ${builddir}/build_logs/*
    fi
    echo '' $param_list > ${builddir}/build_logs/param_list
    eval nohup /bin/sh build-ldas -nohup $param_list > ${builddir}/build_logs/nohup 2>&1
fi
