# Generate packages from the given list
# USAGE: packages_generation $package[…]
packages_generation() {
	# If not explicit packages list is given, generate all packages
	if [ $# -eq 0 ]; then
		local packages_list
		packages_list=$(packages_list)
		packages_generation $packages_list
		return 0
	fi

	information_packages_generation

	local option_package
	option_package=$(option_value 'package')
	case "$option_package" in
		('arch')
			archlinux_packages_metadata "$@"
			archlinux_packages_build "$@"
		;;
		('deb')
			debian_packages_metadata "$@"
			debian_packages_build "$@"
		;;
		('gentoo')
			gentoo_packages_metadata "$@"
			gentoo_packages_build "$@"
		;;
	esac
}

# Print the full list of packages that should be built from the current archive
# If no value is set to PACKAGES_LIST or some archive-specific variant of PACKAGES_LIST,
# the following default value is returned: "PKG_MAIN".
# USAGE: packages_list
# RETURN: a list of package identifiers,
#         separated by line breaks
packages_list() {
	local packages_list
	packages_list=$(context_value 'PACKAGES_LIST')

	# Fall back on the default packages list for the current game engine
	if [ -z "$packages_list" ]; then
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('gamemaker')
				packages_list=$(packages_list_gamemaker)
			;;
			('visionaire')
				packages_list=$(visionaire_packages_list)
			;;
		esac
	fi

	# Fall back of the default packages list (a single package identified by "PKG_MAIN")
	if [ -z "$packages_list" ]; then
		packages_list='PKG_MAIN'
	fi

	local package
	for package in $packages_list; do
		printf '%s\n' "$package"
	done
}

# Check if the given package is included in the list of packages that should be built
# USAGE: package_is_included_in_packages_list $package
# RETURN: 0 if the package is included, 1 if it is not
package_is_included_in_packages_list() {
	local package
	package="$1"

	local packages_list
	packages_list=$(packages_list)

	printf '%s' "$packages_list" |
		grep --quiet --fixed-strings --word-regexp "$package"
}

# Print the list of the packages that would be generated from the given archive.
# USAGE: packages_print_list $archive
# RETURN: a list of package file names, one per line
packages_print_list() {
	local archive
	archive="$1"

	local PLAYIT_CONTEXT_ARCHIVE packages_list package package_name
	set_current_archive "$archive"
	packages_list=$(packages_list)
	for package in $packages_list; do
		package_name=$(package_name "$package")
		printf '%s\n' "$package_name"
	done
}

# Print the file name of the given package
# USAGE: package_name $package
# RETURNS: the file name, as a string
package_name() {
	local package
	package="$1"

	local option_package package_name
	option_package=$(option_value 'package')
	case "$option_package" in
		('arch')
			package_name=$(package_name_archlinux "$package")
		;;
		('deb')
			package_name=$(package_name_debian "$package")
		;;
		('gentoo')
			package_name=$(package_name_gentoo "$package")
		;;
	esac

	printf '%s' "$package_name"
}

# Get the path to the directory where the given package is prepared.
# USAGE: package_path $package
# RETURNS: path to a directory, it is not checked that it exists or is writable
package_path() {
	local package
	package="$1"

	local option_package package_name package_path
	option_package=$(option_value 'package')
	case "$option_package" in
		('arch')
			package_path=$(package_path_archlinux "$package")
		;;
		('deb')
			package_path=$(package_path_debian "$package")
		;;
		('gentoo')
			package_path=$(package_path_gentoo "$package")
		;;
	esac

	printf '%s/packages/%s' "$PLAYIT_WORKDIR" "$package_path"
}

# Print the maintainer string
# USAGE: package_maintainer
# RETURNS: the package maintainer, as a non-empty string
package_maintainer() {
	local maintainer
	maintainer=''

	# Try to get a maintainer string from environment variables used by Debian tools.
	if ! variable_is_empty 'DEBEMAIL'; then
		if ! variable_is_empty 'DEBFULLNAME'; then
			maintainer="$DEBFULLNAME <${DEBEMAIL}>"
		else
			maintainer="$DEBEMAIL"
		fi
	fi
	if [ -n "$maintainer" ]; then
		printf '%s' "$maintainer"
		return 0
	fi

	# Try to get a maintainer string from /etc/makepkg.conf.
	if
		[ -r '/etc/makepkg.conf' ] &&
		grep --quiet '^PACKAGER=' '/etc/makepkg.conf'
	then
		if grep --quiet '^PACKAGER=".*"' '/etc/makepkg.conf'; then
			maintainer=$(sed --silent 's/^PACKAGER="\(.*\)"/\1/p' '/etc/makepkg.conf')
		elif grep --quiet "^PACKAGER='.*'" '/etc/makepkg.conf'; then
			maintainer=$(sed --silent "s/^PACKAGER='\\(.*\\)'/\\1/p" '/etc/makepkg.conf')
		else
			maintainer=$(sed --silent 's/^PACKAGER=\(.*\)/\1/p' '/etc/makepkg.conf')
		fi
	fi
	if [ -n "$maintainer" ]; then
		printf '%s' "$maintainer"
		return 0
	fi

	# Compute a maintainer e-mail from the current hostname and user name,
	# falling back to "user@localhost".
	local hostname
	if command -v 'hostname' >/dev/null 2>&1; then
		hostname=$(hostname)
	elif [ -r '/etc/hostname' ]; then
		hostname=$(cat '/etc/hostname')
	else
		hostname='localhost'
	fi
	local username
	if ! variable_is_empty 'USER'; then
		username="$USER"
	elif command -v 'whoami' >/dev/null 2>&1; then
		username=$(whoami)
	elif command -v 'id' >/dev/null 2>&1; then
		username=$(id --name --user)
	else
		username='user'
	fi
	printf '%s@%s' "$username" "$hostname"
}

# Print the package version string
# USAGE: package_version
# RETURNS: the package version, as a non-empty string
package_version() {
	# Get the version string for the current archive.
	local package_version archive archive_version script_version_string
	archive=$(current_archive)
	archive_version=$(archive_version "$archive")
	script_version_string=$(script_version)
	package_version="${archive_version}+${script_version_string}"

	# Portage does not like some of our version names
	# cf. https://devmanual.gentoo.org/ebuild-writing/file-format/index.html
	local option_package
	option_package=$(option_value 'package')
	case "$option_package" in
		('gentoo')
			package_version=$(gentoo_package_version "$package_version")
		;;
	esac

	printf '%s' "$package_version"
}

