# Debian - Write the metadata for the listed packages
# USAGE: debian_packages_metadata $package[…]
debian_packages_metadata() {
	local package
	for package in "$@"; do
		debian_package_metadata_single "$package"
	done
}

# Debian - Write the metadata for the given package
# USAGE: debian_package_metadata_single $package
debian_package_metadata_single() {
	local package
	package="$1"

	# Create metadata directory.
	local package_path control_directory
	package_path=$(package_path "$package")
	control_directory="${package_path}/DEBIAN"
	mkdir --parents "$control_directory"

	# Write main metadata file (DEBIAN/control).
	local control_file
	control_file="${control_directory}/control"
	debian_package_metadata_control "$package" > "$control_file"

	# Write postinst/prerm scripts, enforce correct permissions.
	local postinst_actions postinst_warnings
	postinst_actions=$(package_postinst_actions "$package")
	postinst_warnings=$(package_postinst_warnings "$package")
	if [ -n "$postinst_actions" ] || [ -n "$postinst_warnings" ]; then
		debian_script_postinst "$package" > "${control_directory}/postinst"
		chmod 755 "${control_directory}/postinst"
	fi
	local prerm_actions
	prerm_actions=$(package_prerm_actions "$package")
	if [ -n "$prerm_actions" ]; then
		debian_script_prerm "$package" > "${control_directory}/prerm"
		chmod 755 "${control_directory}/prerm"
	fi
}

# Print the content of the DEBIAN/control metadata file for the given package
# USAGE: debian_package_metadata_control $package
# RETURN: the contents of the DEBIAN/control file,
#         spanning over multiple lines
debian_package_metadata_control() {
	local package
	package="$1"

	local \
		debian_field_package \
		debian_field_source \
		debian_field_version \
		debian_field_architecture \
		debian_field_maintainer \
		debian_field_installedsize \
		debian_field_provides \
		debian_field_depends \
		debian_field_description
	debian_field_package=$(debian_field_package "$package")
	debian_field_source=$(debian_field_source "$package")
	debian_field_version=$(debian_field_version "$package")
	debian_field_architecture=$(debian_field_architecture "$package")
	debian_field_maintainer=$(debian_field_maintainer "$package")
	debian_field_installedsize=$(debian_field_installedsize "$package")
	debian_field_provides=$(debian_field_provides "$package")
	debian_field_depends=$(debian_field_depends "$package")
	debian_field_description=$(debian_field_description "$package")

	cat <<- EOF
	Package: $debian_field_package
	Source: $debian_field_source
	Version: $debian_field_version
	Architecture: $debian_field_architecture
	Multi-Arch: foreign
	Maintainer: $debian_field_maintainer
	Installed-Size: $debian_field_installedsize
	Section: non-free/games
	EOF
	if [ -n "$debian_field_provides" ]; then
		cat <<- EOF
		Conflicts: $debian_field_provides
		Provides: $debian_field_provides
		Replaces: $debian_field_provides
		EOF
	fi
	if [ -n "$debian_field_depends" ]; then
		cat <<- EOF
		Depends: $debian_field_depends
		EOF
	fi
	cat <<- EOF
	Description: $debian_field_description
	EOF
}

# Debian - Build a list of packages
# USAGE: debian_packages_build $package[…]
debian_packages_build() {
	local package
	for package in "$@"; do
		debian_package_build_single "$package"
	done
}

# Debian - Build a single package
# USAGE: debian_package_build_single $package
debian_package_build_single() {
	local package
	package="$1"

	local package_path
	package_path=$(package_path "$package")

	local path_output_directory package_name generated_package_path
	path_output_directory=$(path_output_directory)
	package_name=$(package_name "$package")
	# TODO: The following path could be computed from a dedicated function.
	generated_package_path="${path_output_directory}/${package_name}"

	# Skip packages already existing,
	# unless called with --overwrite.
	local option_overwrite
	option_overwrite=$(option_value 'overwrite')
	if
		[ "$option_overwrite" -eq 0 ] &&
		[ -e "$generated_package_path" ]
	then
		information_package_already_exists "$package_name"
		return 0
	fi

	# Set the common dpkg-deb options
	local dpkg_options
	## Create all files and directories with owner:group = root:root.
	dpkg_options='--root-owner-group'

	# Use old .deb format if the package is going over the size limit for the modern format
	local package_size
	package_size=$(debian_field_installedsize "$package")
	if [ "$package_size" -gt 9700000 ]; then
		warning_debian_size_limit "$package"
		export PLAYIT_DEBIAN_OLD_DEB_FORMAT=1
		dpkg_options="${dpkg_options:-} --deb-format=0.939000"
	fi

	# Set compression setting
	local option_compression
	option_compression=$(option_value 'compression')
	case "$option_compression" in
		('none')
			dpkg_options="${dpkg_options:-} -Znone"
		;;
		('speed')
			dpkg_options="${dpkg_options:-} -Zgzip"
		;;
		('size')
			if [ "$package_size" -gt 9700000 ]; then
				## Old .deb format 0.939000 is not compatible with xz compression.
				dpkg_options="${dpkg_options:-} -Zgzip"
			else
				dpkg_options="${dpkg_options:-} -Zxz"
			fi
		;;
		('auto')
			if [ "$package_size" -gt 9700000 ]; then
				## Old .deb format 0.939000 is not compatible with xz compression.
				dpkg_options="${dpkg_options:-} -Zgzip"
			fi
		;;
	esac

	# Run the actual package generation, using dpkg-deb
	local TMPDIR
	information_package_building "$package_name"
	## We need to explicitly export TMPDIR, or dpkg-deb will not pick it up.
	export TMPDIR="$PLAYIT_WORKDIR"
	if ! dpkg-deb ${dpkg_options:-} --build "$package_path" "$generated_package_path" 1>/dev/null
	then
		error_package_generation_failed "$package_name"
		return 1
	fi
}

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

	local package_id package_version package_architecture package_name
	package_id=$(package_id "$package")
	package_version=$(package_version)
	package_architecture=$(debian_field_architecture "$package")
	package_name="${package_id}_${package_version}_${package_architecture}.deb"

	printf '%s' "$package_name"
}

# Get the path to the directory where the given package is prepared,
# relative to the directory where all packages are stored
# USAGE: package_path_debian $package
# RETURNS: relative path to a directory, as a string
package_path_debian() {
	local package
	package="$1"

	local package_name package_path
	package_name=$(package_name "$package")
	package_path="${package_name%.deb}"

	printf '%s' "$package_path"
}

