#!/usr/bin/env bash
#-*- mode: shell-script; -*-

prefix=/usr/local

srcdir=$(readlink -f $(dirname $0))
objdir=$(readlink -f ${objdir:-${PWD}})
output=${output:-${objdir}/.config}

usage() {
    echo "Usage: $0 [<options>]

  --help                print this message
  --prefix=<DIR>        set install root dir as <DIR>        (default: /usr/local)
  --bindir=<DIR>        set executable install dir as <DIR>  (default: \${prefix}/bin)
  --libdir=<DIR>        set library install dir as <DIR>     (default: \${prefix}/lib)
  --mandir=<DIR>        set manual doc install dir as <DIR>  (default: \${prefix}/share/man)
  --objdir=<DIR>        set build dir as <DIR>               (default: \${PWD})
  --sysconfdir=<DIR>    override the etc dir as <DIR>
  --with-elfutils=<DIR> search for elfutils in <DIR>/include and <DIR>/lib

  -p                    preserve old setting

  Some influential environment variables:
    ARCH           Target architecture    e.g. arm, aarch64, or x86_64
    CROSS_COMPILE  Specify the compiler prefix during compilation
                   e.g. CC is overridden by \$(CROSS_COMPILE)gcc
    CFLAGS         C compiler flags
    LDFLAGS        linker flags
"
    exit 1
}

# preserve old settings
preserve() {
    if [ -f ${output} ]; then
	while read pre opt op val; do
	    # do not change directory settings (to prevent confusion)
	    if [ "${opt:3}" = "dir" ]; then
		continue
	    fi

	    if [ "$op" = ":=" -o "$op" = "=" ]; then
		eval "$opt=\"$val\""
	    fi
	done < ${output}
    fi
}

while getopts ":ho:-:p" opt; do
    case "$opt" in
        -)
	    # process --long-options
	    case "$OPTARG" in
                help)  usage ;;
                *=*)   opt=${OPTARG%%=*}; val=${OPTARG#*=}
                       eval "${opt/-/_}='$val'" ;;
                *)     ;;
            esac
	    ;;
        o)       output=$OPTARG ;;
        p)       preserve ;;
        *)       usage ;;
    esac
done
shift $((OPTIND - 1))

for arg; do
    opt=${arg%%=*}
    val=${arg#*=}
    eval "$opt='$val'"
done

if [ -z "$ARCH" ]; then
    uname_M=$(uname -m 2>/dev/null || echo not)
    ARCH=$(echo $uname_M | sed -e s/i.86/i386/ -e s/arm.*/arm/ )
    if [ "$ARCH" = "x86_64" ] && echo "$CFLAGS" | grep -w m32 ; then
        ARCH=i386
    fi
fi

bindir=${bindir:-${prefix}/bin}
libdir=${libdir:-${prefix}/lib}
etcdir=${etcdir:-${prefix}/etc}
mandir=${mandir:-${prefix}/share/man}

if [ "$etcdir" = /usr/etc ]; then
    etcdir=/etc
fi
if [ -n "$sysconfdir" ]; then
    etcdir=$sysconfdir
fi

CC=${CC:-${CROSS_COMPILE}gcc}
LD=${LD:-${CROSS_COMPILE}ld}

# objdir can be changed, reset output
objdir=$(readlink -f ${objdir})
output=${output:-${objdir}/.config}

#
# this is needed to suppress warning from make below.
# otherwise it'll get the following warning
# when called from make -jN.
#
# warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
#
MAKEFLAGS=
MAKEOVERRIDES=

export CC CFLAGS LD LDFLAGS

make -siC ${srcdir}/check-deps check-clean
make -siC ${srcdir}/check-deps check-build

if [ ! -e ${srcdir}/check-deps/have_libelf ] && [ ! -f ${with_elfutils}/lib/libelf.so ]; then
    echo "Error: cannot find 'libelf' (from elfutils): Please install it first."
    echo "Otherwise, please install it using \"misc/install-elfutils.sh\" script."
    exit 1
fi

cat >$output <<EOF
# this file is generated automatically
override prefix := $prefix
override bindir := $bindir
override libdir := $libdir
override mandir := $mandir
override etcdir := $etcdir
EOF

if [ ! -z $with_elfutils ]; then
    echo "override elfdir := $with_elfutils" >> $output
fi

cat >>$output <<EOF

override ARCH   := $ARCH
override CC     := $CC
override LD     := $LD
override CFLAGS  = $CFLAGS
override LDFLAGS = $LDFLAGS

override srcdir := $srcdir
override objdir := $objdir
EOF

if [ $(id -u) -eq 0 ]; then
    chmod 666 $output
fi

if [ "$srcdir" != "$objdir" ]; then
    cat > $objdir/Makefile <<EOF
ARCH := $ARCH

srcdir := $srcdir
objdir := $objdir

export ARCH srcdir objdir

MAKEFLAGS = --no-print-directory

all: prepare
	@\$(MAKE) -C \$(srcdir)

clean:
	@rm -rf arch libmcount libtraceevent utils
	@rm -f uftrace version.h *.o *.op

prepare:
	@mkdir -p arch/\$(ARCH) libmcount libtraceevent utils

install:
	@\$(MAKE) -C \$(srcdir) install

test: all
	@\$(MAKE) -C \$(srcdir)/tests TESTARG="\$(TESTARG)" test

.PHONY: all clean prepare test install
EOF
    if [ $(id -u) -eq 0 ]; then
        chmod 666 $objdir/Makefile
    fi
fi
