#!/bin/bash # non-executable, but put this there as a hint to text editors
# This may be included with or without `set -euE`

#   Copyright (c) 2012-2014 by Luke Shumaker <lukeshu@sbcglobal.net>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

LIBREUSER="${SUDO_USER:-$USER}"
if [[ $LIBREUSER == $USER ]]; then
	LIBREHOME=$HOME
else
	LIBREHOME="$(eval echo ~$LIBREUSER)"
fi
if [[ -z ${XDG_CONFIG_HOME:-} ]]; then
	export XDG_CONFIG_HOME="${LIBREHOME}/.config"
fi
if [[ -z ${XDG_CACHE_HOME:-} ]]; then
	export XDG_CACHE_HOME="${LIBREHOME}/.cache"
fi

# Low-level generic functions ##################################################

# Usage: list_files $slug
# Lists the configuration files to be considered for $slug.
# Later files should take precedence over earlier files.
list_files() {
	local slug=$1
	case $slug in
		abs)
			echo /etc/$slug.conf
			echo "$LIBREHOME/.$slug.conf"
			;;
		makepkg)
			if [[ ${MAKEPKG_CONF:-} != /etc/$slug.conf && -r ${MAKEPKG_CONF:-} ]]; then
				echo "$MAKEPKG_CONF"
			else
				echo /etc/$slug.conf
				echo "$LIBREHOME/.$slug.conf"
			fi
			;;
		libretools)
			echo /etc/$slug.conf
			echo "$XDG_CONFIG_HOME/libretools/$slug.conf"
			;;
		*)
			echo /etc/libretools.d/$slug.conf
			echo "$XDG_CONFIG_HOME/libretools/$slug.conf"
			;;
	esac
}

# Usage: list_envvars $slug
# Lists the environmental variables that take precedence over the configuration
# files for $slug.
list_envvars() {
	local slug=$1
	case $slug in
		makepkg)
			printf '%s\n' \
				PKGDEST SRCDEST SRCPKGDEST LOGDEST \
				BUILDDIR \
				PKGEXT SRCEXT \
				GPGKEY PACKAGER
			;;
		libretools)
			printf '%s\n' \
				DIFFPROG
			;;
		*) :;;
	esac
}

# High-level generic functions #################################################

# Usage: load_files $slug
# Loads the configuration files for $slug in the proper order.
load_files() {
	local slug=$1
	local var
	local file

	# Save the existing versions at _VARNAME
	for var in $(list_envvars $slug); do
		[[ -n ${!var:-} ]] && eval "_$var=\${$var}"
	done

	# Load the files
	for file in $(list_files $slug); do
		if [[ -r $file ]]; then
			. "$file" || return 1
		fi
	done

	# Restore the _SAVED versions
	for var in $(list_envvars $slug); do
		eval "$var=\${_$var:-\${$var:-}}"
	done
}

# Usage: check_vars $slug VAR1 VAR2...
# Check whether the variables listed are properly set.
# If not, it prints a message saying to set them in the configuration file(s)
# for $slug.
check_vars() (
	local slug=$1; shift

	local ret=0

	local VAR
	for VAR in "$@"; do
		if [[ -z ${!VAR:-} ]]; then
			type print &>/dev/null || . libremessages
			if [[ $(list_files $slug|wc -l) -gt 1 ]]; then
				_l print "Configure '%s' in one of:" "$VAR"
				list_files $slug | sed 's/./  -> &/'
			else
				_l print "Configure '%s' in '%s'" "$VAR" "$(list_files $slug)"
			fi
			ret=1
		fi
	done >&2

	if [[ $ret != 0 ]]; then
		return 1
	fi
)

# Usage: get_var <slug> <var_name> <default_value>
# Does not work with arrays
get_var() (
	set +euE
	local slug=$1
	local setting=$2
	local default=$3
	load_files "$slug"
	printf '%s' "${!setting:-${default}}"
)

# Usage: set_var <slug> <var_name> <value>
# Does not work with arrays
set_var() {
	local slug=$1
	local key=$2
	local val=$3
	local file
	for file in $(list_files "$slug"|tac); do
		if [[ -w $file ]]; then
			sed -i "/^\s*$key=/d" "$file"
			printf '%s=%q\n' "$key" "$val" >> "$file"
			return 0
		fi
	done
	return 1
}

# PKGBUILD (not configuration, per se) #########################################

unset_PKGBUILD() {
	# This routine is based primarily off of the PKGBUILD(5) man-page,
	# version 4.1.2, dated 2013-06-18.

	# From the "OPTIONS AND DIRECTIVES" section (in order of mention)
	unset -v pkgname pkgver
	unset -f pkgver
	unset -v pkgrel pkgdesc epoch url license install changelog source
	unset -v noextract md5sums sha{1,256,384,512}sums groups arch backup
	unset -v depends makedepends checkdepends optdepends conflicts provides
	unset -v replaces options

	# From the "PACKAGING FUNCTIONS" section (in order of mention)
	unset -f package prepare build check

	# From the "PACKAGE SPLITTING" section
	unset -f $(declare -f|sed -n 's/^\(package_\S*\) ()\s*$/\1/p')
	unset -v pkgbase

	# These are used by the `librefetch` program
	unset -v mksource mknoextract mkmd5sums mksha{1,256,384,512}sums
	unset -v mkdepends
	unset -f mksource
}

load_PKGBUILD() {
	local file=${1:-./PKGBUILD}
	unset_PKGBUILD
	CARCH="$(get_var makepkg CARCH "`uname -m`")"
	. "$file"
}