#!/usr/bin/env bash

#   Licensed to the Apache Software Foundation (ASF) under one
#   or more contributor license agreements.  See the NOTICE file
#   distributed with this work for additional information
#   regarding copyright ownership.  The ASF licenses this file
#   to you under the Apache License, Version 2.0 (the
#   "License"); you may not use this file except in compliance
#   with the License.  You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

host="@HOST_GUESS@"
prefix="@prefix@"
exec_prefix="@exec_prefix@"
libdir="@libdir@"
localstatedir="@localstatedir@"

INSTALLDIR=`eval echo "@libexecdir@"`
INCLUDEDIR=`eval echo "@includedir@"`
CPPFLAGS="$CPPFLAGS -I$INCLUDEDIR @OPENSSL_INCLUDES@"
CFLAGS="$CFLAGS @AM_CFLAGS@"
CXXFLAGS="$CXXFLAGS @AM_CXXFLAGS@"
LIBS="$LIBS @LIBS@ @OPENSSL_LIBS@"
BUILD=
DEBUGECHO=

if [ -z "$CC" ]; then
	CC="@CC@"
fi
if [ -z "$CXX" ]; then
	CXX="@CXX@"
fi

debug() {
	if [ -n "$DEBUGECHO" ]; then
		echo $*
	fi
}

bail() {
	echo tsxs: $*
	exit 1
}

usage() {
	cat <<EOF
$0 : a tool to compile, link and install trafficserver plugins.

Compilation and Linking Options:
-o modulename.so                        ## the name of the module
-I include                              ## add -Iinclude to CFLAGS
-L library path                         ## add -Lpath to LDFLAGS
-l library                              ## add -llib to the LDFLAGS
-v                                      ## verbose, turn on debugging

Installation Options:
-o modulename.so                        ## the name of the module
-i                                      ## install the object

Query Options:
-q varname                              ## query a Traffic Server build variable

Example:
  $0 -I/foo/include -L/foo/lib -lsomelib -o tsmodule.so src1.c src2.c ...

EOF

}

query() {
  case $1 in
    CC) echo @CC@ ;;
    CXX) echo @CXX@ ;;
    CFLAGS) echo $CFLAGS ;;
    CXXFLAGS) echo $CXXFLAGS ;;
	CPPFLAGS) echo $CPPFLAGS ;;
	LIBS) echo $LIBS ;;
	LDFLAGS) echo $LDFLAGS ;;
    PREFIX) echo @prefix@ ;;
    SYSCONFDIR) echo @sysconfdir@ ;;
    INCLUDEDIR) echo @includedir@ ;;
    LIBEXECDIR) echo @libexecdir@ ;;
    BINDIR) echo @bindir@ ;;
    LOCALSTATEDIR) echo @localstatedir@ ;;
    RUNTIMEDIR) echo @runtimedir@ ;;
    LOGDIR) echo @logdir@ ;;
    *) bail "unrecognized query label: $1" ;;
  esac
}

compile() {
	SRC=$1
	extension=`echo $SRC | sed -e 's/^.*\.//g'`
	case $extension in
		c)
			MY_CFLAGS="$CPPFLAGS $CFLAGS"
			MY_CC=$CC
			;;
		cpp|cxx|cc|CPP|CXX|CC|C)
			MY_CFLAGS="$CPPFLAGS $CXXFLAGS"
			MY_CC=$CXX
			;;
		lo|o|a)
			OBJS="${OBJS} ${SRC}"
			BUILD=1
			return
			;;
		*)
			bail "unrecognized input file: $SRC"
			;;
	esac

	obj=`echo $SRC | sed -e 's/\.[a-z]*$/\.lo/g;'`
	echo "  compiling $SRC -> $obj"
	debug "$MY_CC $MY_CFLAGS $PICFLAGS -c $SRC -o $obj"
	$MY_CC $MY_CFLAGS $PICFLAGS -c $SRC -o $obj ||
		bail "compilation failed: $MY_CC $MY_CFLAGS $PICFLAGS -c $SRC -o $obj"
	OBJS="$OBJS $obj"
	BUILD=1
}

case $host in
*-*-darwin*)
        LDFLAGS="$LDFLAGS @OPENSSL_LDFLAGS@"
        CPPFLAGS="$CPPFLAGS"
        PICFLAGS="-fPIC"
        MODULELD="$CC -bundle -flat_namespace -undefined suppress"
        MODULELDXX="$CXX -bundle -flat_namespace -undefined suppress"
        MODULEEXT=bundle
        RLDFLAG="-Wl,-rpath,"
        ;;
*-*-solaris*)
        PICFLAGS="-fpic"
        if test "x$CC" != "xgcc" ; then
                CFLAGS="$CFLAGS -mt"
        	PICFLAGS="-Kpic"
        fi
        MODULELD="$CC -G"
        MODULELDXX="$CXX -G"
        MODULEEXT=so
        RLDFLAG="-R"
        WHOLE_ARCHIVE="-Wl,-z -Wl,allextract"
        NOWHOLE_ARCHIVE="-Wl,-z -Wl,defaultextract"
        ;;
*-*-linux*)
        LDFLAGS="$LDFLAGS @OPENSSL_LDFLAGS@ -Wl,-E"
        CPPFLAGS="$CPPFLAGS"
        PICFLAGS="-fpic"
        MODULELD="$CC -shared"
        MODULELDXX="$CXX -shared"
        MODULEEXT=so
        RLDFLAG="-Wl,--rpath="
        WHOLE_ARCHIVE="-Wl,--whole-archive"
        NOWHOLE_ARCHIVE="-Wl,--no-whole-archive"
        ;;
*-*-freebsd*)
        PICFLAGS="-fpic"
        MODULELD="$CC -shared"
        MODULELDXX="$CXX -shared"
        MODULEEXT=so
        RLDFLAG="-Wl,--rpath="
        ;;
*)
        PICFLAGS="-fpic"
        MODULELD="$CC -shared"
        MODULEEXT=so
        RLDFLAG="-Wl,--rpath="
        ;;
esac

files=()

LD=$MODULELD
while getopts "hivl:L:I:c:C:o:q:" OPTION
do
	case $OPTION in
	v)
		DEBUGECHO=1
		;;
	h)
		usage
		exit 1
		;;
  q)
    query "$OPTARG"
    ;;
	I)
		CPPFLAGS="$CPPFLAGS -I$OPTARG"
		;;
	L)
		LDFLAGS="$LDFLAGS -L$OPTARG $RLDFLAG$OPTARG"
		;;
	l)
		LIBS="$LIBS -l$OPTARG"
		;;
	o)
		OBJ=$OPTARG
		;;
	i)
		if [[ "$INSTALLDIR" = /nix/store* ]]; then
			bail "unsupported option: -i is disabled on Nix"
		fi
		INSTALL=1
		;;
	c)
		files[${#files[@]}]="$OPTARG"
		;;
	C)
		files[${#files[@]}]="$OPTARG"
		;;
	esac
done
shift $(( OPTIND - 1))

for file in "${files[@]}" "$@"; do
	compile $file
done

if [ "$BUILD" = "1" -a -n "$OBJ" ]; then
	echo "  linking -> $OBJ"
	debug "$LD $LDFLAGS -o $OBJ $OBJS $LIBS"
	$LD $LDFLAGS -o $OBJ $OBJS $LIBS ||
		bail "link failed: $LD $LDFLAGS -o $OBJ $OBJS $LIBS"
fi

if [ -n "$OBJ" ]; then
	if [ -r "$OBJ" ]; then
		if [ "$INSTALL" = "1" ]; then
			echo "  installing $OBJ -> $INSTALLDIR/$OBJ"
			cp $OBJ ${DESTDIR}${INSTALLDIR}/${OBJ}
			chmod 0755 ${DESTDIR}${INSTALLDIR}/${OBJ}
		fi
	else
		echo "No $OBJ"
	fi
fi
