# /usr/share/abuild/functions.sh

sysconfdir=/etc
sharedir=${ABUILD_SHAREDIR:-/usr/share/abuild}
program=${0##*/}

arch_to_triplet() {
	case "$1" in
	aarch64)	echo "aarch64-alpine-linux-musl" ;;
	aarch64_be)	echo "aarch64_be-alpine-linux-musl" ;;
	armel)		echo "armv5-alpine-linux-musleabi" ;;
	armhf)		echo "armv6-alpine-linux-musleabihf" ;;
	armv7)		echo "armv7-alpine-linux-musleabihf" ;;
	loongarch32)	echo "loongarch32-alpine-linux-musl" ;;
	loongarchx32)	echo "loongarchx32-alpine-linux-musl" ;;
	loongarch64)	echo "loongarch64-alpine-linux-musl" ;;
	mips)           echo "mips-alpine-linux-musl" ;;
	mips64)         echo "mips64-alpine-linux-musl" ;;
	mipsel)         echo "mipsel-alpine-linux-musl" ;;
	mips64el)       echo "mips64el-alpine-linux-musl" ;;
	ppc)		echo "powerpc-alpine-linux-musl" ;;
	ppc64)		echo "powerpc64-alpine-linux-musl" ;;
	ppc64le)	echo "powerpc64le-alpine-linux-musl" ;;
	riscv32)	echo "riscv32-alpine-linux-musl" ;;
	riscv64)	echo "riscv64-alpine-linux-musl" ;;
	s390x)		echo "s390x-alpine-linux-musl" ;;
	sh2eb)		echo "sh2eb-alpine-linux-muslfdpic" ;;
	sh3)		echo "sh3-alpine-linux-musl" ;;
	sh4)		echo "sh4-alpine-linux-musl" ;;
	x86)		echo "i586-alpine-linux-musl" ;;
	x86_64)		echo "x86_64-alpine-linux-musl" ;;
	*)		echo "unknown" ;;
	esac
}

# Compat for some aports
arch_to_hostspec() {
	arch_to_triplet "$@"
}

triplet_to_arch() {
	case "$1" in
	aarch64-*-*-*)		echo "aarch64" ;;
	aarch64_be-*-*-*)	echo "aarch64_be" ;;
	arm*-*-*-*eabi)		echo "armel" ;;
	armv6*-*-*-*eabihf)	echo "armhf" ;;
	armv7*-*-*-*eabihf)	echo "armv7" ;;
	i[0-9]86-*-*-*)		echo "x86" ;;
	loongarch32-*-*-*)	echo "loongarch32" ;;
	loongarchx32-*-*-*)	echo "loongarchx32" ;;
	loongarch64-*-*-*)	echo "loongarch64" ;;
	mips-*-*-*)             echo "mips" ;;
	mips64-*-*-*)           echo "mips64" ;;
	mipsel-*-*-*)           echo "mipsel" ;;
	mips64el-*-*-*)         echo "mips64el" ;;
	powerpc-*-*-*)		echo "ppc" ;;
	powerpc64-*-*-*)	echo "ppc64" ;;
	powerpc64le-*-*-*)	echo "ppc64le" ;;
	riscv32-*-*-*)		echo "riscv32" ;;
	riscv64-*-*-*)		echo "riscv64" ;;
	s390x-*-*-*)		echo "s390x" ;;
	sh2eb-*-*-*)		echo "sh2eb" ;;
	sh3-*-*-*)		echo "sh3" ;;
	sh4-*-*-*)		echo "sh4" ;;
	x86_64-*-*-*)		echo "x86_64" ;;
	*)
		echo "Couldn't determine arch from triplet: $1" >&2
		exit 1
		;;
	esac
}

triplet_to_libc() {
	case "$1" in
	*-*-*-uclibc*)	echo "uclibc" ;;
	*-*-*-musl*)	echo "musl" ;;
	*-*-*-gnu*)	echo "glibc" ;;
	*)
		echo "Couldn't determine libc from triplet: $1" >&2
		exit 1
		;;
	esac
}

readconfig() {
	local _APORTSDIR _REPODEST _SRCDEST _ABUILD_USERDIR
	local _CC=cc _CXX=c++ _LD=ld _CARCH _CHOST _CTARGET _CPPFLAGS _CFLAGS _CXXFLAGS _LDFLAGS
	local _MAKEFLAGS _PACKAGER _USE_COLORS _USE_CCACHE
	local _BUILDCC _BUILDCXX _BUILDLD _BUILDCPPFLAGS _BUILDCXXFLAGS _BUILDCFLAGS
	local _BUILDLDFLAGS
	local gitbase=
	[ -n "${APORTSDIR+x}" ] && _APORTSDIR=$APORTSDIR
	[ -n "${REPODEST+x}" ] && _REPODEST=$REPODEST
	[ -n "${SRCDEST+x}" ] && _SRCDEST=$SRCDEST
	[ -n "${ABUILD_USERDIR+x}" ] && _ABUILD_USERDIR=$ABUILD_USERDIR
	[ -n "${CC+x}" ] && _CC=$CC
	[ -n "${CXX+x}" ] && _CXX=$CXX
	[ -n "${LD+x}" ] && _LD=$LD
	[ -n "${CARCH+x}" ] && _CARCH=$CARCH
	[ -n "${CHOST+x}" ] && _CHOST=$CHOST
	[ -n "${CTARGET+x}" ] && _CTARGET=$CTARGET
	[ -n "${CPPFLAGS+x}" ] && _CPPFLAGS=$CPPFLAGS
	[ -n "${CFLAGS+x}" ] && _CFLAGS=$CFLAGS
	[ -n "${CXXFLAGS+x}" ] && _CXXFLAGS=$CXXFLAGS
	[ -n "${LDFLAGS+x}" ] && _LDFLAGS=$LDFLAGS
	[ -n "${BUILDCC+x}" ] && _BUILDCC=$BUILDCC
	[ -n "${BUILDCXX+x}" ] && _BUILDCXX=$BUILDCXX
	[ -n "${BUILDCPPFLAGS+x}" ] && _BUILDCPPFLAGS=$BUILDCPPFLAGS
	[ -n "${BUILDCXXFLAGS+x}" ] && _BUILDCXXFLAGS=$BUILDCXXFLAGS
	[ -n "${BUILDCFLAGS+x}" ] && _BUILDCFLAGS=$BUILDCFLAGS
	[ -n "${BUILDLDFLAGS+x}" ] && _BUILDLDFLAGS=$BUILDLDFLAGS
	[ -n "${MAKEFLAGS+x}" ] && _MAKEFLAGS=$MAKEFLAGS
	[ -n "${PACKAGER+x}" ] && _PACKAGER=$PACKAGER
	[ -n "${USE_COLORS+x}" ] && _USE_COLORS="$USE_COLORS"
	[ -n "${USE_CCACHE+x}" ] && _USE_CCACHE="$USE_CCACHE"
	: ${ABUILD_DEFCONF:=$sharedir/default.conf}
	[ -f "$ABUILD_DEFCONF" ] && . "$ABUILD_DEFCONF"
	: ${ABUILD_CONF:=$sysconfdir/abuild.conf}
	[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
	ABUILD_USERDIR=${_ABUILD_USERDIR-${ABUILD_USERDIR:-$HOME/.abuild}}
	: ${ABUILD_USERCONF:=$ABUILD_USERDIR/abuild.conf}
	[ -f "$ABUILD_USERCONF" ] && . "$ABUILD_USERCONF"
	APORTSDIR=${_APORTSDIR-$APORTSDIR}

	: ${git:=git}
	gitbase=$($git rev-parse --show-toplevel 2>/dev/null) || true # already is -P
	if [ -d "$APORTSDIR" ]; then
		APORTSDIR=$(cd "$APORTSDIR"; pwd -P)
	elif [ -z "$APORTSDIR" ] && [ -d "$HOME/aports" ]; then
		APORTSDIR=$(cd "$HOME/aports"; pwd -P)
	else
		if [ -n "$gitbase" ]; then
			case $($git remote get-url origin 2>/dev/null || true) in
			# '.git' for SSH URLs, and no suffix for HTTPS URLs
			*/aports|*/aports.git) APORTSDIR=$gitbase ;;
			*) APORTSDIR= ;;
			esac
		else
			APORTSDIR=
		fi
	fi
	# source any .abuild file at the aports root, but only if we are currently in aports tree
	[ -n "$APORTSDIR" ] && [ -f "$APORTSDIR/.abuild" ] && [ "$APORTSDIR" = "$gitbase" ] && . "$APORTSDIR/.abuild"
	REPODEST=${_REPODEST-$REPODEST}
	SRCDEST=${_SRCDEST-$SRCDEST}
	CC=${_CC-$CC}
	CXX=${_CXX-$CXX}
	LD=${_LD-$LD}
	CARCH=${_CARCH-$CARCH}
	CHOST=${_CHOST-$CHOST}
	CTARGET=${_CTARGET-$CTARGET}
	CPPFLAGS=${_CPPFLAGS-$CPPFLAGS}
	CFLAGS=${_CFLAGS-$CFLAGS}
	CXXFLAGS=${_CXXFLAGS-$CXXFLAGS}
	LDFLAGS=${_LDFLAGS-$LDFLAGS}
	BUILDCC=${_BUILDCC-$BUILDCC}
	BUILDCXX=${_BUILDCXX-$BUILDCXX}
	BUILDLD=${_BUILDLD-$BUILDLD}
	BUILDCPPFLAGS=${_BUILDCPPFLAGS-$BUILDCPPFLAGS}
	BUILDCXXFLAGS=${_BUILDCXXFLAGS-$BUILDCXXFLAGS}
	BUILDCFLAGS=${_BUILDCFLAGS-$BUILDCFLAGS}
	BUILDLDFLAGS=${_BUILDLDFLAGS-$BUILDLDFLAGS}
	MAKEFLAGS=${_MAKEFLAGS-$MAKEFLAGS}
	PACKAGER=${_PACKAGER-$PACKAGER}
	USE_COLORS=${_USE_COLORS-$USE_COLORS}
	USE_CCACHE=${_USE_CCACHE-$USE_CCACHE}

	# export BUILD variables because it is used as variables specific to the platform running the compiler
	# instead of the platform the compiled binaries are supposed to run on
	export BUILDCC="$CC"
	export BUILDCXX="$CXX"
	export BUILDLD="$LD"
	export BUILDCPPFLAGS="$CPPFLAGS"
	export BUILDCXXFLAGS="$CXXFLAGS"
	export BUILDCFLAGS="$CFLAGS"
	export BUILDLDFLAGS="$LDFLAGS"

	[ -z "$CBUILD" ] && CBUILD="$(${APK:-apk} --print-arch 2>/dev/null || :)"
	[ -z "$CHOST" ] && CHOST="$CBUILD"
	[ -z "$CTARGET" ] && CTARGET="$CHOST"
	[ "$(arch_to_triplet $CBUILD)" != "unknown" ] && CBUILD="$(arch_to_triplet $CBUILD)"
	[ "$(arch_to_triplet $CHOST)" != "unknown" ] && CHOST="$(arch_to_triplet $CHOST)"
	[ "$(arch_to_triplet $CTARGET)" != "unknown" ] && CTARGET="$(arch_to_triplet $CTARGET)"
	if [ -z "$CBUILD" ]; then
		echo "Unable to deduce build architecture. Install apk-tools, or set CBUILD." >&2
		exit 1
	fi

	[ -z "$CARCH" ] && CARCH="$(triplet_to_arch $CHOST)"
	[ -z "$CLIBC" ] && CLIBC="$(triplet_to_libc $CHOST)"
	[ -z "$CBUILD_ARCH" ] && CBUILD_ARCH="$(triplet_to_arch $CBUILD)"
	[ -z "$CTARGET_ARCH" ] && CTARGET_ARCH="$(triplet_to_arch $CTARGET)"
	[ -z "$CTARGET_LIBC" ] && CTARGET_LIBC="$(triplet_to_libc $CTARGET)"

	if [ "$CHOST" != "$CTARGET" ]; then
		# setup environment for creating cross compiler
		[ -z "$CBUILDROOT" ] && export CBUILDROOT="$HOME/sysroot-$CTARGET_ARCH/"
	elif [ "$CBUILD" != "$CHOST" ]; then
		# setup build root
		[ -z "$CBUILDROOT" ] && export CBUILDROOT="$HOME/sysroot-$CTARGET_ARCH/"
		# prepare pkg-config for cross building
		[ -z "$PKG_CONFIG_PATH" ] && export PKG_CONFIG_PATH="${CBUILDROOT}/usr/lib/pkgconfig/:${CBUILDROOT}/usr/share/pkgconfig/"
		[ -z "$PKG_CONFIG_SYSROOT_DIR" ] && export PKG_CONFIG_SYSROOT_DIR="${CBUILDROOT}"
		# libtool bug workaround for extra rpaths
		[ -z "$lt_cv_sys_lib_dlsearch_path_spec" ] && \
			export lt_cv_sys_lib_dlsearch_path_spec="${CBUILDROOT}/lib ${CBUILDROOT}/usr/lib /usr/lib /lib /usr/local/lib"
		# setup cross-compiler
		if [ -z "$CROSS_COMPILE" ]; then
			export CROSS_COMPILE="${CHOST}-"
			export HOSTCC="$CC"
			export HOSTCXX="$CXX"
			export HOSTLD="$LD"
			export HOSTCPPFLAGS="$CPPFLAGS"
			export HOSTCXXFLAGS="$CXXFLAGS"
			export HOSTCFLAGS="$CFLAGS"
			export HOSTLDFLAGS="$LDFLAGS"
			export CC=${CROSS_COMPILE}$CC
			export CXX=${CROSS_COMPILE}$CXX
			export LD=${CROSS_COMPILE}$LD
			export CPPFLAGS="--sysroot=${CBUILDROOT} $CPPFLAGS"
			export CXXFLAGS="--sysroot=${CBUILDROOT} $CXXFLAGS"
			export CFLAGS="--sysroot=${CBUILDROOT} $CFLAGS"
			export LDFLAGS="--sysroot=${CBUILDROOT} $LDFLAGS"
		fi
	fi
	return 0
}
readconfig

# expects $1 to be a package directory in the aports tree ('foo' or 'main/foo')
# outputs APKBUILD's path if successful
aports_buildscript() {
	[ -n "$APORTSDIR" ] || return 1
	if [ "${1#*/}" != "$1" ]; then
		( cd "$APORTSDIR/$1" && [ -f APKBUILD ] && echo "$PWD/APKBUILD" )
	else
		( cd "$APORTSDIR"/*/"$1" && [ -f APKBUILD ] && echo "$PWD/APKBUILD" )
	fi
}

# expects $1 to be a file, or a directory containing an APKBUILD, or a package directory in the aports tree
# outputs APKBUILD's path if successful (doesn't verify that it's a valid APKBUILD)
any_buildscript() {
	if [ -f "$1" ]; then
		echo "$1"
	elif [ -d "$1" ]; then
		[ -f "$1/APKBUILD" ] || return 1
		echo "$1/APKBUILD"
	else
		aports_buildscript "$1" || return 1
	fi
}

apk_tar() {
	if [ -n "$SOURCE_DATE_EPOCH" ]; then
		set -- --mtime="@$SOURCE_DATE_EPOCH" "$@"
	fi
	tar --format=posix \
		--pax-option=exthdr.name=%d/PaxHeaders/%f,atime:=0,ctime:=0 \
		--no-recursion --null -f - -c "$@"
}

# output functions
msg() {
	[ -n "$quiet" ] && return 0
	local prompt="$GREEN>>>${NORMAL}"
	printf "${prompt} %s\n" "$1" >&2
}

msg2() {
	[ -n "$quiet" ] && return 0
	#      ">>> %s"
	printf "    %s\n" "$1" >&2
}

warning() {
	local prompt="${YELLOW}>>> WARNING:${NORMAL}"
	printf "${prompt} %s\n" "$1" >&2
}

warning2() {
	#      ">>> WARNING: %s\n"
	printf "             %s\n" "$1" >&2
}

error() {
	local prompt="${RED}>>> ERROR:${NORMAL}"
	printf "${prompt} %s\n" "$1" >&2
}

error2() {
	#      ">>> ERROR:
	printf "           %s\n" "$1" >&2
}

set_xterm_title() {
	if [ "$TERM" = xterm ] && [ -n "$USE_COLORS" ]; then
		 printf "\033]0;$1\007" >&2
	fi
}

disable_colors() {
	NORMAL=""
	STRONG=""
	RED=""
	GREEN=""
	YELLOW=""
	BLUE=""
}

enable_colors() {
	NORMAL="\033[1;0m"
	STRONG="\033[1;1m"
	RED="\033[1;31m"
	GREEN="\033[1;32m"
	YELLOW="\033[1;33m"
	BLUE="\033[1;34m"
}

if [ "$USE_COLORS" = force ]; then
	enable_colors
elif [ -n "$USE_COLORS" ] && [ -t 1 ]; then
	enable_colors
else
	disable_colors
fi

# caller may override
cleanup() {
	return 0
}

die() {
	error "$@"
	cleanup
	exit 1
}
