#!/bin/bash
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1

if [[ -z $1 ]] ; then
	__helpers_die "${0##*/}: at least one argument needed"
	exit 1
fi

# setup compression stuff
PORTAGE_COMPRESS=${PORTAGE_COMPRESS-bzip2}
[[ -z ${PORTAGE_COMPRESS} ]] && exit 0

if [[ ${PORTAGE_COMPRESS_FLAGS+set} != "set" ]] ; then
	case ${PORTAGE_COMPRESS} in
		bzip2|gzip)  PORTAGE_COMPRESS_FLAGS="-9";;
	esac
fi

# decompress_args(suffix, binary)
#	- suffix: the compression suffix to work with
#	- binary: the program to execute that'll compress/decompress
# new_args: global array used to return revised arguments
decompress_args() {
	local suffix=$1 binary=$2
	shift 2

	# Initialize the global new_args array.
	new_args=()
	declare -a decompress_args=()
	local x i=0 decompress_count=0
	for x in "$@" ; do
		if [[ ${x%$suffix} = $x ]] ; then
			new_args[$i]=$x
		else
			new_args[$i]=${x%$suffix}
			decompress_args[$decompress_count]=$x
			((decompress_count++))
		fi
		((i++))
	done

	if [ $decompress_count -gt 0 ] ; then
		${binary} "${decompress_args[@]}"
		if [ $? -ne 0 ] ; then
			# Apparently decompression failed for one or more files, so
			# drop those since we don't want to compress them twice.
			new_args=()
			local x i=0
			for x in "$@" ; do
				if [[ ${x%$suffix} = $x ]] ; then
					new_args[$i]=$x
					((i++))
				elif [[ -f ${x%$suffix} ]] ; then
					new_args[$i]=${x%$suffix}
					((i++))
				else
					# Apparently decompression failed for this one, so drop
					# it since we don't want to compress it twice.
					true
				fi
			done
		fi
	fi
}

case $1 in
	--suffix)
		[[ -n $2 ]] && __vecho "${0##*/}: --suffix takes no additional arguments" 1>&2

		if [[ ! -e ${T}/.ecompress.suffix ]] ; then
			set -e
			tmpdir="${T}"/.ecompress$$.${RANDOM}
			mkdir "${tmpdir}"
			cd "${tmpdir}"
			# we have to fill the file enough so that there is something
			# to compress as some programs will refuse to do compression
			# if it cannot actually compress the file
			echo {0..1000} > compressme
			${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS} compressme > /dev/null
			# If PORTAGE_COMPRESS_FLAGS contains -k then we need to avoid
			# having our glob match the uncompressed file here.
			suffix=$(echo compressme.*)
			[[ -z $suffix || "$suffix" == "compressme.*" ]] && \
				suffix=$(echo compressme*)
			suffix=${suffix#compressme}
			cd /
			rm -rf "${tmpdir}"
			echo "${suffix}" > "${T}/.ecompress.suffix"
		fi
		cat "${T}/.ecompress.suffix"
		;;
	--bin)
		[[ -n $2 ]] && __vecho "${0##*/}: --bin takes no additional arguments" 1>&2

		echo "${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
		;;
	--queue)
		shift
		ret=0
		for x in "${@/%/.ecompress.file}" ; do
			>> "$x"
			((ret|=$?))
		done
		[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
		exit $ret
		;;
	--dequeue)
		[[ -n $2 ]] && __vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
		find "${D}" -name '*.ecompress.file' -print0 \
			| sed -e 's:\.ecompress\.file::g' \
			| ${XARGS} -0 ecompress
		find "${D}" -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
		;;
	--*)
		__helpers_die "${0##*/}: unknown arguments '$*'"
		exit 1
		;;
	*)
		# Since dodoc calls ecompress on files that are already compressed,
		# perform decompression here (similar to ecompressdir behavior).
		decompress_args ".Z" "gunzip -f" "$@"
		set -- "${new_args[@]}"
		decompress_args ".gz" "gunzip -f" "$@"
		set -- "${new_args[@]}"
		decompress_args ".bz2" "bunzip2 -f" "$@"
		set -- "${new_args[@]}"

		mask_ext_re=""
		set -f
		for x in $PORTAGE_COMPRESS_EXCLUDE_SUFFIXES ; do
			mask_ext_re+="|$x"
		done
		set +f
		mask_ext_re="^(${mask_ext_re:1})\$"
		declare -a filtered_args=()
		i=0
		for x in "$@" ; do
			[[ ${x##*.} =~ $mask_ext_re ]] && continue
			[[ -s ${x} ]] || continue
			filtered_args[$i]=$x
			((i++))
		done
		[ $i -eq 0 ] && exit 0
		set -- "${filtered_args[@]}"

		# If a compressed version of the file already exists, simply
		# delete it so that the compressor doesn't whine (bzip2 will
		# complain and skip, gzip will prompt for input)
		suffix=$(ecompress --suffix)
		[[ -n ${suffix} ]] && echo -n "${@/%/${suffix}$'\001'}" | \
			tr '\001' '\000' | ${XARGS} -0 rm -f
		# Finally, let's actually do some real work
		"${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
		ret=$?
		[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
		exit $ret
		;;
esac
