# List the requirements for the current game script
# USAGE: requirements_list
# RETURN: a list for required commands, one per line
requirements_list() {
	# A variable is used to prevent error code mangling
	local requirements_list

	# List explicit requirements
	requirements_list=$(requirements_list_explicit)

	# List requirements for the current archive integrity setting
	requirements_list="$requirements_list
	$(requirements_list_checksum)"

	# List requirements for the current output package format setting
	requirements_list="$requirements_list
	$(requirements_list_package)"

	# List requirements for the current icons setting
	requirements_list="$requirements_list
	$(requirements_list_icons)"

	# List requirements for the current archive
	requirements_list="$requirements_list
	$(requirements_list_archive)"

	# If a WINE init .reg script is to be generated,
	# ensure that iconv is available
	local regedit_initial_content
	regedit_initial_content=$(regedit_initial_content)
	if [ -n "$regedit_initial_content" ]; then
		requirements_list="$requirements_list
		iconv"
	fi

	printf '%s' "$requirements_list" | list_clean
}

# List requirements explictly set from the game script
# USAGE: requirements_list_explicit
# RETURN: a list for required commands,
#         separated by line breaks
requirements_list_explicit() {
	context_value 'REQUIREMENTS_LIST'
}

# List requirements for the current archive integrity setting
# USAGE: requirements_list_checksum
# RETURN: a list for required commands, one per line
requirements_list_checksum() {
	local option_checksum requirements
	option_checksum=$(option_value 'checksum')
	case "$option_checksum" in
		('md5')
			requirements='md5sum'
		;;
	esac

	if ! variable_is_empty 'requirements'; then
		printf '%s\n' $requirements
	fi
}

# List requirements for the current output package format setting
# USAGE: requirements_list_package
# RETURN: a list for required commands, one per line
requirements_list_package() {
	local option_package requirements
	option_package=$(option_value 'package')
	case "$option_package" in
		('arch')
			# bsdtar and gzip are required for .MTREE
			requirements='bsdtar gzip'
		;;
		('deb')
			requirements='dpkg-deb'
		;;
		('gentoo')
			requirements='tar bzip2'
		;;
	esac

	if ! variable_is_empty 'requirements'; then
		printf '%s\n' $requirements
	fi
}

# List requirements for the current icons setting
# USAGE: requirements_list_icons
# RETURN: a list for required commands, one per line
requirements_list_icons() {
	# Return early if icons inclusion is disabled
	local option_icons
	option_icons=$(option_value 'icons')
	if [ "$option_icons" -eq 0 ]; then
		return 0
	fi

	# Fetch the list of icons.
	local icons_list
	icons_list=$(icons_list_all)
	# Return early if there is no icon for the current game script
	if [ -z "$icons_list" ]; then
		return 0
	fi

	# Print requirements for each icon.
	local icon icon_path game_engine
	game_engine=$(game_engine)
	for icon in $icons_list; do
		## This is allowed to fail for Unity3D games,
		## because we might not know the icon path before the archive extraction.
		case "$game_engine" in
			('unity3d')
				icon_path=$(icon_path "$icon" 2>/dev/null) || continue
			;;
			(*)
				icon_path=$(icon_path "$icon")
			;;
		esac
		case "$icon_path" in
			(*'.png')
				printf '%s\n' 'identify'
			;;
			(*'.bmp'|*'.ico')
				printf '%s\n' 'identify' 'convert'
			;;
			(*'.exe')
				printf '%s\n' 'identify' 'convert' 'wrestool'
			;;
		esac
	done
}

# List requirements for the current archive.
# USAGE: requirements_list_archive
requirements_list_archive() {
	local archive
	archive=$(current_archive)

	local requirements_list
	requirements_list=$(
		# Main archive requirements
		requirements_list_archive_single "$archive"
		# Extra parts requirements
		for part_index in $(seq 1 9); do
			archive_part="${archive}_PART${part_index}"
			# Stop looking at the first unset archive extra part.
			if variable_is_empty "$archive_part"; then
				break
			fi
			requirements_list_archive_single "$archive_part"
		done
	)

	# Isolating the pipe use prevents ignored errors when building the list of requirements.
	printf '%s' "$requirements_list" | list_clean
}

# List requirements for the given archive
# USAGE: requirements_list_archive_single $archive
# RETURN: a list for required commands, one per line
requirements_list_archive_single() {
	local archive
	archive="$1"

	local archive_extractor
	archive_extractor=$(archive_extractor "$archive")
	if [ -n "$archive_extractor" ]; then
		printf '%s\n' "$archive_extractor"
		return 0
	fi

	local archive_type requirements
	archive_type=$(archive_type "$archive")
	case "$archive_type" in
		('7z')
			requirements='7zr'
		;;
		('appimage')
			requirements='binwalk unsquashfs'
		;;
		('cabinet')
			requirements='cabextract'
		;;
		('debian')
			requirements='dpkg-deb'
		;;
		('innosetup')
			requirements='innoextract'
		;;
		('installshield')
			requirements='unshield'
		;;
		('iso')
			requirements='bsdtar'
		;;
		('lha')
			requirements='lha'
		;;
		('makeself')
			requirements=$(archive_requirements_makeself_list)
		;;
		('mojosetup')
			requirements=$(archive_requirements_mojosetup_list)
		;;
		('msi')
			requirements='msiextract convmv'
		;;
		('nullsoft-installer')
			requirements='unar'
		;;
		('rar')
			requirements='unar'
		;;
		('tar')
			requirements='tar'
		;;
		('tar.bz2')
			requirements='tar bunzip2'
		;;
		('tar.gz')
			requirements='tar gunzip'
		;;
		('tar.xz')
			requirements='tar unxz'
		;;
		('zip')
			requirements='unzip'
		;;
	esac
	if ! variable_is_empty 'requirements'; then
		printf '%s\n' $requirements
	fi
}

