#!/usr/bin/env bash

########################################################################
# Set various environment variables
########################################################################

# Assume current directory is SAGE_ROOT/build/make
export SAGE_ROOT=`cd ../.. && pwd -P`
export SAGE_SRC="$SAGE_ROOT/src"

# Determine SAGE_LOCAL
. "$SAGE_SRC"/bin/sage-env-config
if [ $? -ne 0 ]; then
    echo "Error: Failed to read sage-env-config.  Did you run configure?"
    exit 1
fi

export SAGE_SHARE="$SAGE_LOCAL/share"
export SAGE_PKGCONFIG="$SAGE_LOCAL/lib/pkgconfig"
export SAGE_LOGS="$SAGE_ROOT/logs/pkgs"

if [ -z "${SAGE_ORIG_PATH_SET}" ]; then
    SAGE_ORIG_PATH=$PATH && export SAGE_ORIG_PATH
    SAGE_ORIG_PATH_SET=True && export SAGE_ORIG_PATH_SET
fi
export PATH="$SAGE_ROOT/build/bin:$SAGE_SRC/bin:$SAGE_LOCAL/bin:$PATH"

export PYTHONPATH="$SAGE_LOCAL"

sage_num_threads_array=$(sage-build-num-threads 2>/dev/null || echo 1 2 1)
sage_num_threads_array="${sage_num_threads_array% *}" # strip third item
export SAGE_NUM_THREADS="${sage_num_threads_array% *}" # keep first item
export SAGE_NUM_THREADS_PARALLEL="${sage_num_threads_array#* }" # keep second item

###############################################################################
# Skip the rest if nothing to do (i.e., to [re]build).
###############################################################################

# Set MAKE to "make" if unset
if [ -z "$MAKE" ]; then
    export MAKE=make
fi

# Make the special target _clean-broken-gcc before trying to build any other
# packages.  This is necessary if configure detected a broken GCC installed
# in Sage; Trac #25011
$MAKE _clean-broken-gcc

# If "make" doesn't understand the -q option (although we require
# GNU make, which supports it), it should exit with a non-zero status
# which is not a problem.
if $MAKE -q "$@" >/dev/null 2>/dev/null; then
    echo "Nothing to (re)build / all up-to-date."
    exit 0
fi

# Dump environment for debugging purposes:
echo "*** ALL ENVIRONMENT VARIABLES BEFORE BUILD: ***"
env | sort
printf '\E[m'
echo "***********************************************"

# look_for_errors: search log files for error messages and print a summary.
# arguments:
# - $1: glob pattern for log files to search
# - $2: N for "tail -N"
# - $3: regular expression to search for
# - $4: type of object ("package" or "documentation")
look_for_errors() {
    # Sort in chronological order by log file.
    for f in `ls -tr $1 2>/dev/null`; do
        # Look for recent error message in log file.
        # Note that "tail -n 20 ..." doesn't work on Solaris.
        if tail -$2 $f 2>/dev/null | grep "$3" &>/dev/null; then
            base_f=`basename $f .log`
            # stat(1) is not portable between Linux and macOS, so we extract it from ls -lf
            timestamp=`ls -l $f | awk -F' ' '{print $6, $7, $8}'` 2> /dev/null
            cat >&2 <<EOF

* $4:         $base_f
  last build time: $timestamp
  log file:        $f
EOF
            if [ $4 = "package" ]; then
                build_dir="${SAGE_BUILD_DIR:-$SAGE_LOCAL/var/tmp/sage/build}/$base_f"
                if [ -d "$build_dir" ]; then
                    cat >&2 <<EOF
  build directory: $build_dir
EOF
                fi
            fi
        fi
    done
}

###############################################################################
# NOW do the actual build:
###############################################################################
time $MAKE "$@"
if [ $? -ne 0 ]; then
    cat >&2 <<EOF
***************************************************************
Error building Sage.

The following package(s) may have failed to build (not necessarily
during this run of 'make $@'):
EOF

    look_for_errors "$SAGE_LOGS/*.log" 20 "^Error" package >&2

    cat >&2 <<EOF

It is safe to delete any log files and build directories, but they
contain information that is helpful for debugging build problems.
WARNING: If you now run 'make' again, the build directory of the
same version of the package will, by default, be deleted. Set the
environment variable SAGE_KEEP_BUILT_SPKGS=yes to prevent this.

EOF
    exit 1

elif [ "$SAGE_CHECK" = "warn" ]; then
    echo "SAGE_CHECK=warn, so scanning the log files. This may take a few seconds."
    # The following warning message must be consistent with SAGE_ROOT/build/bin/sage-spkg (see trac:32781)
    warnings=`look_for_errors "$SAGE_LOGS/*.log" 20 "^Warning: Failures testing package" package`
    if [ -n "$warnings" ]; then
        cat >&2 <<EOF
***************************************************************
Warning: the following package(s) may have failed their test suites
(not necessarily during this run of 'make $@'):
EOF

        echo $warnings >&2
    fi

fi

# Build succeeded.
echo "Sage build/upgrade complete!"

if [ "$1" = "all" ]; then
    echo
    echo "To install small scripts to directly run Sage's versions of GAP,"
    echo "the PARI/GP interpreter, Maxima, or Singular etc. (by typing e.g."
    echo "just 'gap' or 'gp') into a standard 'bin' directory, start Sage"
    echo "by typing 'sage' (or './sage') and enter something like"
    echo
    echo "    install_scripts('/usr/local/bin')"
    echo
    echo "at the Sage command prompt ('sage:')."
    echo
fi
