#!/bin/sh
#
# author: pancake@phreaker.net
#
# installs or removes fake packages into the pkgsrc database.
# creates and manages fake alternatives on pkgsrc.
# allows to hide and show packages from the pkgsrc database.

# variable initialization #
PREFIX=@PREFIX@
PKGDB=@PKGDB@
PKGSRC=@PKGSRC@
PKGHIDE=${PKGDB}/../pkg_hide
if [ -z "${EDITOR}" ]; then
	EDITOR=vi
fi

# help functions #
show_help()
{
cat <<EOF
Usage: pkg_fake [-aAclLprRihH] [pkgname]
Version: 0.3

 fake packages:
   -a : append files to the target fake package PLIST.
   -c : clears target package fake PLIST.
	(useful for pkg_fake -p ezm3 | pkg_fake -a ezm3)
   -i : install a new fake package.
   -l : list all fake packages.
   -p : shows the PLIST of an installed or not package.
   -r : remove a fake package.

 fake alternatives:
   -A : adds fake alternatives to a package.
   -L : list all fake alternatives.
   -R : remove fake alternative support to a package.

 hidding utilities:
   -h : hides the desired package. 
   -H : list all hide packages.
   -u : unhide the selected package.
EOF
}

init_hide()
{
	mkdir -p ${PKGHIDE} 2>&1 >/dev/null || \
	( echo "Cannot create '${PKGHIDE}' directory." && \
	exit 1 )
}

fini_hide()
{
	if [ ! "`ls ${PKGHIDE}`" ]; then
		rm -rf ${PKGHIDE} 2>&1 >/dev/null
	fi
}

list_all()
{
	cd ${PKGDB}
	for A in `ls`; do
		if [ -e "${A}/+FAKE" ]; then
		COMMENT="`cat ${A}/+COMMENT`"
		printf "${A}\t\t${COMMENT}\n"
		fi
	done
}

list_all_alternatives()
{
	cd ${PKGDB}
	for A in `ls`; do
		if [ -e "${A}/+FAKE_ALT" ]; then
		COMMENT="`cat ${A}/+COMMENT`"
		printf "${A}\t\t${COMMENT}\n"
		fi
	done
}

edit_alternatives()
{
	PKG="$1"
	echo "Type in editor the wrapper lines in format:"
	echo "\"bin/python /usr/pkg/bin/python2p3\""
	echo
	echo "press enter" 
	read
	${EDITOR} "${PKGDB}/${PKG}/+ALTERNATIVES"
	pkg_alternatives register "${PKGDB}/${PKG}/+ALTERNATIVES"
}

package_autocompletion()
{
	NAME=$1
	TDIR=$2

	# XXX this check is redundant
	if [ -z "${NAME}" ]; then
		echo "" >/dev/stderr
		echo "Target package name is mandatory." >/dev/stderr
		exit 1
	fi

	MAYBE="`ls ${TDIR} | grep "^${NAME}"`"
	if [ "1" = `echo ${MAYBE} | wc -w` ]; then
		echo "Autocomplenting package name to: ${MAYBE}" >/dev/stderr
		echo ${MAYBE}
	else
		if [ -z "${MAYBE}" ]; then
			echo "Target package does not exists." > /dev/stderr
		else
			echo "There'r more than one alternative for this package:" >/dev/stderr
			echo ${MAYBE} >/dev/stderr
			exit 1
		fi
	fi
}

clear_contents()
{
	PKG=$1
	echo "@name ${PKG}" > ${PKGDB}/${PKG}/+CONTENTS
	echo "@cwd ${PREFIX}" >> ${PKGDB}/${PKG}/+CONTENTS
}

print_plist()
{
	PKGDIR=$1
	cd ${PKGSRC}/${PKG}
	`bmake show-var VARNAME=_GENERATE_PLIST | sed -e 's,; true;,,'` | eval awk `bmake show-var VARNAME=_PLIST_AWK_SCRIPT`
}

# main #
if [ -z "${1}" ]; then
	show_help
	exit 1
fi

case "${1}" in
"-l"|"-L"|"-H")
;;
*)
	if [ -z "${2}" ]; then
	show_help
	echo ""
	echo "!! Target package name is mandatory. !!"
	exit 1
	fi
;;
esac

if [ -z "$1" ]; then break; fi

case $1 in
	"-l") # list all fake packages installed
		list_all
		exit 0
	;;
	"-L") # list all fake alternatives
		list_all_alternatives
		exit 0
	;;
	"-a") # adds files to a fake package
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then 
			echo "Target package required"
			exit 1
		fi
		if [ -e "${PKGDB}/${PKG}/+FAKE" ]; then
			if [ ! "1" = "`cat ${PKGDB}/${PKG}/+CONTENTS | wc -l`" ]; then
				echo "Target package already have PLIST."
				echo "Press ^C to cancel the append."
			fi
			echo "^D or EOF finishes."
			cat >> ${PKGDB}/${PKG}/+CONTENTS
			echo "done"
		else
			echo "This is not a fake package."
		fi
	;;
	"-c") # clears the PLIST file
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then 
			echo "Target package required"
			exit 1
		fi
		clear_contents ${PKG}
		echo "done"
	;;
	"-p") # shows the PLIST of a installed or not package.
		PKG=$2
		if [ -n "`echo ${PKG}| grep /`" ]; then
			if [ ! -d "${PKGSRC}/${PKG}" ]; then
				echo "This package does not exists."
				exit 1
			fi
			print_plist ${PKGSRC}/${PKG}
		else
			PKG=`package_autocompletion "${2}" "${PKGDB}"`
			if [ -z "${PKG}" ]; then
				echo "Package not installed. looking in the pkgsrc tree." > /dev/stderr
				PKG=`pkgfind -qxn1 "${2}"`
				if [ -z "${PKG}" ]; then
					echo "No target package found." >/dev/stderr
					exit 1
				fi
				print_plist ${PKGSRC}/${PKG}
			else
				cat ${PKGDB}/${PKG}/+CONTENTS
			fi
		fi
	;;
	"-i") # install new fake package
		PKG="${2}"
		if [ -z "${PKG}" ]; then 
			echo "Target package required"
			exit 1
		fi
		if [ -d "${PKGDB}/${PKG}" ]; then
			echo "package ${PKG} yet exists."
			exit 1
		fi
		printf "COMMENT="
		read COMMENT
		COMMENT="FAKE ${COMMENT}"
		# create package
		
		mkdir -p "${PKGDB}/${PKG}"
		:> "${PKGDB}/${PKG}/+FAKE"
		clear_contents ${PKG}
		#echo "@name ${PKG}" > "${PKGDB}/${PKG}/+CONTENTS"
		#echo "@cwd ${PREFIX}"   > "${PKGDB}/${PKG}/+CONTENTS"
		echo "OBJECT_FMT=ELF"   > "${PKGDB}/${PKG}/+BUILD_INFO"
		echo "OPSYS=`uname -s`" > "${PKGDB}/${PKG}/+BUILD_INFO" 
		:> "${PKGDB}/${PKG}/+DESC"
		:> "${PKGDB}/${PKG}/+SIZE_ALL"
		:> "${PKGDB}/${PKG}/+SIZE_PKG"
		echo "${COMMENT}" > "${PKGDB}/${PKG}/+COMMENT"

		echo "[i] package created."
		exit 0
	;;
	"-A") # creates a new fake alternative
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then exit 1; fi

		if [ -e "${PKGDB}/${PKG}/+ALTERNATIVES" ]; then
			if [ -e "${PKGDB}/${PKG}/+FAKE_ALT" ]; then
				edit_alternatives ${PKG}
			else
				echo "This is not a valid fake alternatives package (already have a valid ALTERNATIVES)."
			fi
		else
			:> "${PKGDB}/${PKG}/+FAKE_ALT"
			edit_alternatives ${PKG}
		fi
		exit 0
	;;
	"-r") # removes a fake package
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then exit 1; fi

		if [ -e "${PKGDB}/${PKG}/+FAKE" ]; then
			rm -rf "${PKGDB}/${PKG}" 2>&1 >/dev/null
			if [ "$?" = "0" ]; then
				echo "package removed."
				exit 0
			else
				echo "cannot remove pacakge. check permissions."
				exit 1
			fi
		else
			echo "target package isn't fake. not removed."
			exit 1
		fi
	;;
	"-R") # removes a fake alternatives
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then exit 1; fi
		if [ ! -d "${PKGDB}/${PKG}" ]; then
			echo "This package does not exists."
			exit 1
		fi

		if [ -e "${PKGDB}/${PKG}/+FAKE_ALT" ]; then
			pkg_alternatives -gs unregister "${PKGDB}/${PKG}/+ALTERNATIVES"
			rm -f "${PKGDB}/${PKG}/+ALTERNATIVES" &&
			rm -f "${PKGDB}/${PKG}/+FAKE_ALT" &&\
			echo "Fake alternatives removed from ${PKG}"
		else
			echo "this is not a fake alternative package"
		fi
		exit 0;
	;;
# Hidding
	"-h"|"--hide") # hides the desired package.
		init_hide
		PKG=`package_autocompletion "${2}" "${PKGDB}"`
		if [ -z "${PKG}" ]; then exit 1; fi
		if [ -e "${PKGDB}/${PKG}" ]; then
			mv ${PKGDB}/${PKG} ${PKGHIDE}/${PKG}
			exit 0
		else
			echo "Target package is not installed in your system."
			exit 1
		fi
		fini_hide
	;;
	"-u"|"--unhide") # unhides the target package.
		init_hide
		PKG=`package_autocompletion "${2}" "${PKGHIDE}"`
		if [ -z "${PKG}" ]; then exit 1; fi
		if [ -e ${PKGHIDE}/${PKG} ]; then
			mv ${PKGHIDE}/${PKG} ${PKGDB}/${PKG}
			exit 0
		else
			echo "Target package is not installed in your system."
			exit 1
		fi
		fini_hide
	;;
	"-H") # list all hidding packages.
		if [ -d "${PKGHIDE}" ]; then
		ls ${PKGHIDE}
		fi
	;;
	*) # shows help message
		show_help
		exit 0
	;;
esac

exit 1
