#!@GENTOO_PORTAGE_EPREFIX@/bin/bash
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

PARENT_EPREFIX="@GENTOO_PORTAGE_EPREFIX@"
PARENT_CHOST="@GENTOO_PORTAGE_CHOST@"
CHILD_EPREFIX=
CHILD_PROFILE=
CHILD_CHOST=

#
# get ourselfs the functions.sh script for ebegin/eend/etc.
#
for f in \
	/lib/gentoo/functions.sh \
	/etc/init.d/functions.sh \
	/sbin/functions.sh \
; do
	if [[ -r ${PARENT_EPREFIX}${f} ]] ; then
		. "${PARENT_EPREFIX}${f}"
		f=found
		break
	fi
done

if [[ ${f} != found ]] ; then
	echo "Cannot find Gentoo functions, aborting." >&2
	exit 1
fi

for arg in "$@"; do
	case "${arg}" in
	--eprefix=*) CHILD_EPREFIX="${arg#--eprefix=}" ;;
	--profile=*) CHILD_PROFILE="${arg#--profile=}" ;;
	--chost=*)   CHILD_CHOST="${arg#--chost=}" ;;

	--help)
		einfo "$0 usage:"
		einfo "  --eprefix=[PATH]       Path to new EPREFIX to create stacked to the prefix"
		einfo "                         where this script is installed (${PARENT_EPREFIX})"
		einfo "  --profile=[PATH]       The absolute path to the profile to use. This path"
		einfo "                         must point to a directory within ${PARENT_EPREFIX}"
		einfo "  --chost=[CHOST]        The CHOST to use for the new EPREFIX, required if"
		einfo "                         the profile does not set CHOST, or to override."
		exit 0
		;;
	esac
done

#
# sanity check of given values
#

test -n "${CHILD_EPREFIX}" || { eerror "no eprefix argument given"; exit 1; }
test -d "${CHILD_EPREFIX}" && { eerror "${CHILD_EPREFIX} already exists"; exit 1; }
test -n "${CHILD_PROFILE}" || { eerror "no profile argument given"; exit 1; }
test -d "${CHILD_PROFILE}" || { eerror "${CHILD_PROFILE} does not exist"; exit 1; }

if [[ -z ${CHILD_CHOST} ]]
then
	my_lsprofile() {
		(
			cd -P "${1:-.}" || exit 1
			[[ -r ./parent ]] &&
				for p in $(<parent)
				do
					my_lsprofile "${p}" || exit 1
				done
			pwd -P
		)
	}

	for profile in $(my_lsprofile "${CHILD_PROFILE}") missing
	do
		if [[ ${profile} == missing ]]
		then
		  eerror "profile does not set CHOST, need --chost argument"
		  exit 1
		fi
		[[ -s "${profile}/make.defaults" ]] || continue
		grep -q '^[ 	]*CHOST@=@' "${profile}/make.defaults" && break
	done
fi

einfo "creating stacked prefix ${CHILD_EPREFIX}"

#
# functions needed below.
#
eend_exit() {
	eend $1
	[[ $1 != 0 ]] && exit 1
}

#
# create the directories required to bootstrap the least.
#
ebegin "creating directory structure"
(
	set -e
	mkdir -p "${CHILD_EPREFIX}"/var/tmp/portage
	mkdir -p "${CHILD_EPREFIX}"/etc/portage/profile/use.mask
	mkdir -p "${CHILD_EPREFIX}"/etc/portage/profile/use.force
	mkdir -p "${CHILD_EPREFIX}"/etc/portage/env
	mkdir -p "${CHILD_EPREFIX}"/etc/portage/package.env
	ln -s "${PARENT_EPREFIX}"/etc/portage/repos.conf "${CHILD_EPREFIX}"/etc/portage/repos.conf
)
eend_exit $?

#
# create a make.conf and set PORTDIR and PORTAGE_TMPDIR
#
ebegin "creating make.conf"
(
	set -e
	echo "#"
	echo "# These are sane default compiler flags, feel free to adopt them as you like."
	echo "# Extending the flags is done to respect flags probably set by some profile."
	echo "#"
	echo "CFLAGS=\"\${CFLAGS} -O2 -pipe\""
	echo "CXXFLAGS=\"${CXXFLAGS} -O2 -pipe\""
	echo "MAKEOPTS=\"$(portageq envvar MAKEOPTS)\""
	niceness=$(portageq envvar PORTAGE_NICENESS || true)
	[[ -n ${niceness} ]] &&
		echo "PORTAGE_NICENESS=\"${niceness}\""
	echo
	echo "# Mirrors from parent prefix."
	echo "GENTOO_MIRRORS=\"$(portageq envvar GENTOO_MIRRORS || true)\""
	echo
	echo "# Below comes the prefix-stack setup. Only change things"
	echo "# if you know exactly what you are doing!"
	echo "EPREFIX=\"${CHILD_EPREFIX}\""
	echo "PORTAGE_OVERRIDE_EPREFIX=\"${PARENT_EPREFIX}\""
	echo "BROOT=\"${PARENT_EPREFIX}\""
	echo "PORTAGE_TMPDIR=\"\${EPREFIX}/var/tmp\""
	# Since EAPI 7 there is BDEPEND, which is DEPEND in EAPI up to 6.
	# We do not want to pull DEPEND from EAPI <= 6, but RDEPEND only.
	echo "EMERGE_DEFAULT_OPTS=\"--root-deps=rdeps\""
	if [[ -n ${CHILD_CHOST} ]] ; then
		echo "CHOST=\"${CHILD_CHOST}\""
	fi
) > "${CHILD_EPREFIX}"/etc/portage/make.conf
eend_exit $?

ebegin "creating use.mask/prefix-stack"
printf -- '-%s\n' prefix{,-guest,-stack} > "${CHILD_EPREFIX}"/etc/portage/profile/use.mask/prefix-stack
eend_exit $?

ebegin "creating use.force/prefix-stack"
printf -- '%s\n' prefix{,-guest,-stack} > "${CHILD_EPREFIX}"/etc/portage/profile/use.force/prefix-stack
eend_exit $?

ebegin "creating env/host-cc.conf"
cat > "${CHILD_EPREFIX}"/etc/portage/env/host-cc.conf <<-EOM
	CC=${PARENT_CHOST}-gcc
	CXX=${PARENT_CHOST}-g++
	# Inherited compiler flags from parent prefix,
	# as the child prefix may have a different compiler.
	CFLAGS="$(portageq envvar CFLAGS)"
	CXXFLAGS="$(portageq envvar CXXFLAGS)"
	EOM
eend_exit $?

ebegin "creating package.env/prefix-stack"
cat > "${CHILD_EPREFIX}"/etc/portage/package.env/prefix-stack <<-'EOM'
	# merge with the parent's chost. this forces the use of the parent
	# compiler, which generally would be illegal - this is an exception.
	# This is required for example on winnt, because the wrapper has to
	# be able to use/resolve symlinks, etc. native winnt binaries miss
	# that ability, but cygwin binaries don't.
	sys-devel/gcc-config host-cc.conf
	sys-apps/gentoo-functions host-cc.conf
	EOM
eend_exit $?

#
# create the make.profile symlinks.
#
ebegin "creating make.profile"
(
	ln -s "${CHILD_PROFILE}" "${CHILD_EPREFIX}/etc/portage/make.profile"
)
eend_exit $?

#
# adjust permissions of generated files.
#
ebegin "adjusting permissions"
(
	set -e
	chmod 644 "${CHILD_EPREFIX}"/etc/portage/make.conf
	chmod 644 "${CHILD_EPREFIX}"/etc/portage/env/host-cc.conf
	chmod 644 "${CHILD_EPREFIX}"/etc/portage/package.env/prefix-stack
)
eend_exit $?

#
# now merge some basics.
#
ebegin "installing required basic packages"
(
	set -e
	export PORTAGE_CONFIGROOT@=@"${CHILD_EPREFIX}"
	export EPREFIX@=@"${CHILD_EPREFIX}"
	export PORTAGE_OVERRIDE_EPREFIX@=@"${PARENT_EPREFIX}"

	# let baselayout create the directories
	USE@=@"${USE} build" \
	emerge --verbose --nodeps --oneshot \
		'>=baselayout-prefix-2.6'

	# In prefix-stack, app-portage/prefix-toolkit does
	# install/update an etc/portage/profile/packages file,
	# removing all @system packages from current make.profile,
	# and adding itself to @system set instead.
	emerge --verbose --nodeps --oneshot \
		app-portage/prefix-toolkit

	# In prefix-stack, prefix-toolkit does have an RDEPEND on them,
	# to hold them in the @system set.
	emerge --verbose --nodeps --oneshot \
		sys-apps/gentoo-functions \
		app-portage/elt-patches \
		sys-devel/gnuconfig \
		sys-devel/gcc-config

	# get eventual dependencies, add to world
	emerge --verbose --update --deep \
		app-portage/prefix-toolkit

	# select the stack wrapper profile from gcc-config
	env -i PORTAGE_CONFIGROOT="${CHILD_EPREFIX}" \
		"$(type -P bash)" "${CHILD_EPREFIX}"/usr/bin/gcc-config 1
)
eend_exit $?

#
# wow, all ok :)
#
ewarn
ewarn "all done. don't forget to tune ${CHILD_EPREFIX}/etc/portage/make.conf."
ewarn "to enter the new prefix, run \"${CHILD_EPREFIX}/startprefix\"."
ewarn
