#!/bin/sh
# 
# Copyright (c) 2010-2013 Baptiste Daroussin <bapt@FreeBSD.org>
# Copyright (c) 2012-2013 Bryan Drewery <bdrewery@FreeBSD.org>
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

LC_ALL=C
unset SHELL
SAVED_TERM=$TERM
unset TERM
POUDRIERE_VERSION='3.2.8'

usage() {
	cat << EOF
Usage: poudriere [-e etcdir] [-N] command [options]

Options:
    -A          -- Force colors, even if not in a TTY
    -e etcdir   -- Specify an alternate etc/ dir where poudriere configuration
                   resides.
    -N          -- Disable colors
    -v          -- Be verbose; show more information. Use twice to enable
                   debug output
Commands:
    bulk        -- Generate packages for given ports
    distclean   -- Remove old distfiles
    daemon      -- Launch the poudriere daemon
    help        -- Show usage
    image       -- Generate images
    jail        -- Manage the jails used by poudriere
    logclean    -- Remove old logfiles
    ports       -- Create, update or delete the portstrees used by poudriere
    pkgclean    -- Remove packages that are no longer needed
    options     -- Configure ports options
    queue       -- Queue a build request
    status      -- Get the status of builds
    testport    -- Launch a test build of a given port
    version     -- Show the version of poudriere
EOF
	exit 1
}

SETX=""
while getopts "Ae:Nvx" FLAG; do
	case "${FLAG}" in
	A)
		FORCE_COLORS=1
		;;
	e)
		if [ ! -d "$OPTARG" ]; then
			echo "Error: argument '$OPTARG' not a directory"
			exit 1
		fi
		export POUDRIERE_ETC=$OPTARG
		;;
	N)
		USE_COLORS="no"
		;;
	v)
		VERBOSE=$((${VERBOSE:-0} + 1))
		;;
	x)
		SETX="-x"
		;;
	*)
		usage
		;;
	esac
done

shift $((OPTIND-1))

[ $# -lt 1 ] && usage

POUDRIEREPATH=`realpath $0`
if [ "${POUDRIEREPATH%src/bin/poudriere}" != "${POUDRIEREPATH}" ]; then
	# It is running from src/bin/poudriere in checkout
	POUDRIEREPREFIX=${POUDRIEREPATH%/bin/*}
	LIBEXECPREFIX="${POUDRIEREPATH%/src/bin/poudriere}"
elif [ "${POUDRIEREPATH%/bin/*}" = "${POUDRIEREPATH}" ]; then
	# It is running in a build directory or the source checkout as
	# ./poudriere.  Lookup VPATH to resolve to source checkout if in
	# build directory.
	[ -f Makefile ] && VPATH="$(make -V VPATH)"
	POUDRIEREPREFIX="${POUDRIEREPATH%/poudriere}${VPATH:+/${VPATH}}/src"
	[ -n "${VPATH}" ] && POUDRIEREPREFIX="$(realpath "${POUDRIEREPREFIX}")"
	LIBEXECPREFIX="${POUDRIEREPATH%/poudriere}"
else
	# Running from PREFIX/bin/poudriere
	POUDRIEREPREFIX=${POUDRIEREPATH%/bin/*}
	LIBEXECPREFIX="${POUDRIEREPREFIX}/libexec/poudriere"
fi
SCRIPTPREFIX=${POUDRIEREPREFIX}/share/poudriere

CMD=$1
shift
CMD_ENV=
[ -n "${POUDRIERE_ETC}" ] && CMD_ENV="${CMD_ENV} POUDRIERE_ETC=${POUDRIERE_ETC}"
[ -n "${USE_COLORS}" ] && CMD_ENV="${CMD_ENV} USE_COLORS=${USE_COLORS}"
CMD_ENV="${CMD_ENV} LIBEXECPREFIX=${LIBEXECPREFIX}"
CMD_ENV="${CMD_ENV} PATH=${LIBEXECPREFIX}:${PATH}:/sbin:/usr/sbin"
CMD_ENV="${CMD_ENV} POUDRIERE_VERSION=${POUDRIERE_VERSION}"
CMD_ENV="${CMD_ENV} POUDRIEREPATH=${POUDRIEREPATH}"
[ -n "${VERBOSE}" ] && CMD_ENV="${CMD_ENV} VERBOSE=${VERBOSE}"
[ -n "${FORCE_COLORS}" ] && CMD_ENV="${CMD_ENV} FORCE_COLORS=${FORCE_COLORS}"

# Handle special-case commands first.
case "${CMD}" in
version)
	echo "${POUDRIERE_VERSION}"
	exit 0
	;;
help)
	usage
	;;
jails)
	CMD="jail"
	;;
options|testport|bulk)
	CMD_ENV="${CMD_ENV} SAVED_TERM=${SAVED_TERM}"
esac

# Allow proxy env to pass through for fetching jails/ports
case "${CMD}" in
ports|jail)
	while read envvar envvalue; do
		case "${envvar}" in
		FETCH_BIND_ADDRESS|FTP_*|ftp_*|HTTP_*|http_*|SSL_|NO_PROXY|no_proxy|MAKEOBJDIRPREFIX)
			CMD_ENV="${CMD_ENV} ${envvar}=${envvalue}"
			;;
		esac
	done <<-EOF
	$(env | sed -Ee 's,^([^=]*)=(.*),\1 \2,')
	EOF
	;;
esac

SCRIPTPATH="${SCRIPTPREFIX}/${CMD}.sh"
CMD_ENV="${CMD_ENV} SCRIPTPATH=${SCRIPTPATH} SCRIPTPREFIX=${SCRIPTPREFIX}"

case "${CMD}" in
api|bulk|distclean|daemon|image|jail|logclean|ports|options|pkgclean|queue|status|testport)
	;;
*)
	echo "Unknown command '${CMD}'"
	usage
	;;
esac

case "${CMD}" in
jail|ports|daemon|status|options)
	;;
*)
	SET_ERREXIT=-e
	;;
esac

: ${UMASK:=022}
umask ${UMASK}

: ${SH:=sh}

exec env -i ${CMD_ENV} ${SH} ${SET_ERREXIT} ${SETX} "${SCRIPTPATH}" "$@"
