# Set up the base archive
# USAGE: init_archive
# RETURN: 0 if the archive is found,
#         1 if it is missing
init_archive() {
	local archive_identifier
	archive_identifier='SOURCE_ARCHIVE'

	# A file path might have already been set, if one has been given on the command line.
	# If this is the case, we only want to use an archive that uses the same name.
	## The output redirection must be done inside the subshell, or bash --posix will ignore it.
	archive_name_expected=$(archive_name "$archive_identifier" 2>/dev/null) || true

	# Filter the list of supported archives to keep only the ones with the same name than the provided one
	local archives_list archive archive_name archive_candidates_list
	archives_list=$(archives_list)
	for archive in $archives_list; do
		archive_name=$(archive_name "$archive")
		if [ "$archive_name" = "$archive_name_expected" ]; then
			archive_candidates_list="${archive_candidates_list:-}
			$archive"
		fi
	done
	# Drop empty lines
	archive_candidates_list=$(printf '%s' "${archive_candidates_list:-}" | list_clean)
	# Throw an error if no archive candidate has been found
	if [ -z "$archive_candidates_list" ]; then
		error_archive_not_found $archives_list
		return 1
	fi

	# If there is only one archive candidate, set it as the current archive
	local archive_candidates_number
	archive_candidates_number=$(printf '%s\n' "$archive_candidates_list" | wc --lines)
	if [ "$archive_candidates_number" -eq 1 ]; then
		init_archive_set_properties "$archive_identifier" "$archive_candidates_list"
		return 0
	fi

	# If there are multiple archive candidates, discriminate between them using the archive hash
	local archive_name archive_hash
	archive_name=$(archive_name "$archive_identifier")
	archive_hash=$(archive_hash_md5_computed "$archive_name")
	local archive archive_hashes_list archive_candidate_hash
	for archive in $archive_candidates_list; do
		archive_hashes_list=$(archive_hashes_list_md5 "$archive")
		for archive_candidate_hash in $archive_hashes_list; do
			if [ "$archive_candidate_hash" = "$archive_hash" ]; then
				init_archive_set_properties "$archive_identifier" "$archive"
				return 0
			fi
		done
	done

	# Throw an error if no archive candidate has the expected hash
	error_archive_not_found $archives_list
	return 1
}

# Set the properties of the base archive
# USAGE: init_archive_set_properties $archive_identifier $archive_candidate
init_archive_set_properties() {
	local archive_identifier archive_candidate
	archive_identifier="$1"
	archive_candidate="$2"

	local archive_name archive_path
	archive_name=$(archive_name "$archive_candidate")
	archive_path=$(archive_path "$archive_candidate")

	export "${archive_identifier}_NAME=${archive_name}"
	export "${archive_identifier}_PATH=${archive_path}"

	# Cache the path to the candidate archive, to prevent the need to re-compute it later.
	export "${archive_candidate}_PATH=${archive_path}"

	# Old game scripts relying on `archive_extraction 'SOURCE_ARCHIVE'` instead of `archive_extraction_default`
	# expect either SOURCE_ARCHIVE_TYPE or SOURCE_ARCHIVE_EXTRACTOR to be set.
	local archive_extractor archive_extractor_options archive_type
	archive_extractor=$(archive_extractor "$archive_candidate")
	archive_extractor_options=$(archive_extractor_options "$archive_candidate")
	archive_type=$(archive_type "$archive_candidate")
	export "${archive_identifier}_EXTRACTOR=${archive_extractor}"
	export "${archive_identifier}_EXTRACTOR_OPTIONS=${archive_extractor_options}"
	export "${archive_identifier}_TYPE=${archive_type}"

	# Export the context archive
	set_current_archive "$archive_candidate"

	# Some old game scripts might expect the variable $SOURCE_ARCHIVE to be set
	export SOURCE_ARCHIVE="$archive_path"

	# Look for extra parts
	archive_initialize_extra_parts "$archive_candidate"

	# Update the list of archives that are going to be used
	archives_used_add "$archive_candidate"

	# Archives integrity can not yet be checked, because $PLAYIT_WORKDIR might not be set yet,
	# and it is required to cache computed hashes. archives_integrity_check must be called later.
}

# Check for the presence of extra required archives
# USAGE: init_extra_archives_required
init_extra_archives_required() {
	if ! archives_required_extra_presence_check; then
		# Delete temporary files
		working_directory_cleanup

		exit 1
	fi
}

# Check for the presence of extra optional archives
# USAGE: init_extra_archives_optional
init_extra_archives_optional() {
	# Check for the presence of an optional icons pack
	local icons_pack_name
	icons_pack_name=$(context_value 'ARCHIVE_OPTIONAL_ICONS_NAME')
	if [ -n "$icons_pack_name" ]; then
		## Set contextual values, for game scripts with support for multiple games.
		ARCHIVE_OPTIONAL_ICONS_NAME=$(context_value 'ARCHIVE_OPTIONAL_ICONS_NAME')
		ARCHIVE_OPTIONAL_ICONS_MD5=$(context_value 'ARCHIVE_OPTIONAL_ICONS_MD5')
		ARCHIVE_OPTIONAL_ICONS_URL=$(context_value 'ARCHIVE_OPTIONAL_ICONS_URL')
		export ARCHIVE_OPTIONAL_ICONS_NAME ARCHIVE_OPTIONAL_ICONS_MD5 ARCHIVE_OPTIONAL_ICONS_URL
		archive_initialize_optional \
			'ARCHIVE_ICONS' \
			'ARCHIVE_OPTIONAL_ICONS'
		if ! archive_is_available 'ARCHIVE_ICONS'; then
			warning_optional_archive_missing_icons 'ARCHIVE_OPTIONAL_ICONS'
		fi
	fi
}

# Check the archives integrity
# USAGE: init_archives_integrity_check
init_archives_integrity_check() {
	if ! archives_integrity_check; then
		# Delete temporary files
		working_directory_cleanup

		exit 1
	fi
}

