# Print the type of the given application
# USAGE: application_type $application
# RETURN: the application type keyword, from the supported values:
#         - dosbox
#         - java
#         - mono
#         - native
#         - renpy
#         - scummvm
#         - wine
#         or an empty string if the type is not set and could not be guessed
application_type() {
	local application
	application="$1"

	local application_type
	application_type=$(context_value "${application}_TYPE")

	# If no type has been explicitely set, try to guess one
	## Try to detect ScummVM applications
	if [ -z "$application_type" ]; then
		local application_scummid
		application_scummid=$(application_scummvm_scummid "$application")
		if [ -n "$application_scummid" ]; then
			application_type='scummvm'
		fi
	fi
	## Try to detect the application type based of the binary MIME type
	if [ -z "$application_type" ]; then
		if [ -n "${PLAYIT_WORKDIR:-}" ]; then
			application_type=$(application_type_guess_from_file "$application")
		fi
	fi

	# Return early if no type has been found
	if [ -z "$application_type" ]; then
		return 0
	fi

	# Check that a supported type has been fetched
	case "$application_type" in
		( \
			'custom' | \
			'dosbox' | \
			'java' | \
			'mono' | \
			'native' | \
			'renpy' | \
			'scummvm' | \
			'web' | \
			'wine' \
		)
			## This is a supported type, no error to throw.
		;;
		(*)
			error_unknown_application_type "$application_type"
			return 1
		;;
	esac

	printf '%s' "$application_type"
}

# Try to find the application type from the MIME type of its binary file.
# An empty string is returned if no type could be guessed.
# USAGE: application_type_guess_from_file $application
application_type_guess_from_file() {
	local application application_type
	application="$1"
	application_type=''

	# Get the path to the application binary.
	local application_exe
	application_exe=$(application_exe "$application")
	## If no binary is found for the current package,
	## try to find one for any of the packages.
	if [ -z "$application_exe" ]; then
		local package packages_list
		packages_list=$(packages_list)
		for package in $packages_list; do
			application_exe=$(
				set_current_package "$package"
				application_exe "$application"
			)
			if [ -n "$application_exe" ]; then
				break
			fi
		done
	fi
	## Return early if no binary is set for the current application.
	if [ -z "$application_exe" ]; then
		return 0
	fi

	# Compute the full path to the application binary.
	local application_exe_path
	application_exe_path=$(application_exe_path "$application_exe")
	## Return early if no binary file can be found for the given application.
	if [ -z "$application_exe_path" ]; then
		return 0
	fi

	# Guess the application type from its binary file MIME type.
	local file_type file_type_extended
	file_type=$(file_type "$application_exe_path")
	case "$file_type" in
		( \
			'application/x-executable' | \
			'application/x-pie-executable' | \
			'application/x-sharedlib' \
		)
			application_type='native'
		;;
		('text/html')
			application_type='web'
		;;
		( \
			'application/x-dosexec' | \
			'application/vnd.microsoft.portable-executable' \
		)
			file_type_extended=$(env --ignore-environment file --brief --dereference "$application_exe_path")
			case "$file_type_extended" in
				( \
					'DOS executable (COM)'* | \
					'MS-DOS executable'* \
				)
					application_type='dosbox'
				;;
				(*'Mono/.Net assembly'*)
					application_type='mono'
				;;
				( \
					'PE32 executable'* | \
					'PE32+ executable'* \
				)
					application_type='wine'
				;;
			esac
		;;
		('application/octet-stream')
			file_type_extended=$(env --ignore-environment file --brief --dereference "$application_exe_path")
			case "$file_type_extended" in
				('MS-DOS executable'*)
					application_type='dosbox'
				;;
			esac
		;;
	esac

	printf '%s' "$application_type"
}

# Print the type of the first application.
# USAGE: application_default_type
application_default_type() {
	local applications_list application application_type
	applications_list=$(applications_list)
	if [ -z "$applications_list" ]; then
		error_applications_list_empty
	fi
	application=$(printf '%s' "$applications_list" | head --lines=1)
	application_type=$(application_type "$application")

	printf '%s' "$application_type"
}

