#! /bin/bash
# Copyright 2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Written by Yuri Vasilevski <yvasilev@gentoo.org>

CACHEDIR="/tmp/gwn"

. /sbin/functions.sh

fetch_snapshot () {

	[ ! -d "${CACHEDIR}" ] && install -d "${CACHEDIR}"

	if [ -e "${CACHEDIR}/portage-latest.tar.bz2" ] ; then
		ebegin "\"latest\" snapshot found, moving to \"previous\"." >&2
		mv -f "${CACHEDIR}/portage-latest.tar.bz2" "${CACHEDIR}/portage-previous.tar.bz2"
		eend >&2
	fi
	
	ebegin "Fetching new \"latest\" snapshot." >&2
	for mirror in $(portageq gentoo_mirrors) ; do
		if wget -c "${mirror}/snapshots/portage-latest.tar.bz2" -O "${CACHEDIR}/portage-latest.tar.bz2" ; then
			break
		fi
	done
	eend >&2
}

genlist_snapshots () {
	ebegin "Generating packages list form \"latest\" snapshot" >&2
	if [ -e "${CACHEDIR}/portage-latest.tar.bz2" ] ; then
		tar tjf "${CACHEDIR}/portage-latest.tar.bz2" | grep '/Manifest$' \
			| sed -e 's:^portage/:: ; s:/Manifest$::' | sort > "${CACHEDIR}/portage-latest.list"
		eend >&2
	else
		eend 1 >&2
		eerror "No \"latest\" snapshot, you need to download one." >&2
		clean
		exit 1
	fi

	ebegin "Generating packages list from \"previous\" snapshot" >&2
	if [ -e "${CACHEDIR}/portage-previous.tar.bz2" ] ; then
		tar tjf "${CACHEDIR}/portage-previous.tar.bz2" | grep '/Manifest$' \
			| sed -e 's:^portage/:: ; s:/Manifest$::' | sort > "${CACHEDIR}/portage-previous.list"
		eend >&2
	else
		eend 1 >&2
		eerror "No \"previous\" snapshot, you need to download one." >&2
		clean
		exit 1
	fi
}

compere_lists () {
	if [[ ! -e "${CACHEDIR}/portage-latest.list" ]] || [[ ! -e "${CACHEDIR}/portage-previous.list" ]] ; then
		eerror "Packages lists generation failed, can't compute new packages." >&2
		exit 1
	fi

	diff "${CACHEDIR}/portage-previous.list" "${CACHEDIR}/portage-latest.list" \
		| sed -n -e '/^> / {s/> // ; p}'
}

unpack_ebuilds () {
	local unpack_dirs="portage/eclass"
	local pkg

	for pkg in $(compere_lists) ; do
		unpack_dirs="$unpack_dirs portage/$pkg/*.ebuild"
	done

	install -d "${CACHEDIR}/tmp"

	ebegin "Unpacking new packages from \"latest\" snapshot" >&2
	tar xjf "${CACHEDIR}/portage-latest.tar.bz2" -C "${CACHEDIR}/tmp" --wildcards $unpack_dirs
	eend >&2
}

print_xml () {
	local cat=$1
	local name=$2
	local dscr="$3"
	shift 3

	echo
	echo "<tr>"
	echo "<ti><uri link=\"http://packages.gentoo.org/packages/?category=${cat};name=${name}\">${cat}/${name}</uri></ti>"

	if [ "$#" = 1 ] ; then
		echo "<ti><uri link=\"${1}\">Homepage</uri></ti>"
	else
		echo -n "<ti>"
		for (( i = 1 ; i < $# ; i++ )) ; do
			echo -n "<uri link=\"$(eval echo \$$i)\">$i</uri> "
		done
		echo -n "<uri link=\"$(eval echo \$$#)\">$#</uri>"
		echo "</ti>"
	fi

	echo "<ti>$description</ti>"
	echo "</tr>"
}

print_pkg_info () {
	local pkg="$1"
	
	ebegin "Processing $pkg" >&2

	local ebuild="$(ls -1 "${CACHEDIR}/tmp/portage/$pkg/" | tail -n 1)"

	local homepage="$(PORTDIR_OVERLAY="${CACHEDIR}/tmp/portage" portageq metadata / ebuild "${pkg%/*}/${ebuild/.ebuild/}" HOMEPAGE)"
	local description="$(PORTDIR_OVERLAY="${CACHEDIR}/tmp/portage" portageq metadata / ebuild "${pkg%/*}/${ebuild/.ebuild/}" DESCRIPTION)"

	print_xml "${pkg%/*}" "${pkg#*/}" "${description}" $homepage

	eend >&2
}

print_info () {
	einfo "Generating packages table:" >&2
	eindent

	ebegin "Processing header" >&2
	echo '<table>'
	echo
	echo '<tr>'
	echo '<th>Package:</th>'
	echo '<th>Homepage:</th>'
	echo '<th>Description:</th>'
	echo '</tr>'
	eend >&2

	for pkg in $(compere_lists) ; do
		print_pkg_info "$pkg"
	done

	ebegin "Processing footer" >&2
	echo
	echo '</table>'
	eend >&2

	eoutdent
}

clean () {
	ebegin "Cleaning" >&2

	rm -rf "${CACHEDIR}/tmp"
	rm -f "${CACHEDIR}/portage-previous.list" "${CACHEDIR}/portage-latest.list"

	eend >&2
}

print_usage () {
	echo "Usage: $0 [-f] > file" >&2
	echo >&2
	echo "Options:" >&2
	echo "  -f                        Fetches new \"latest\" portage snapshot" >&2
	echo "                            moving \"latest\" to \"previous\" if it exist." >&2
	echo >&2
	exit 1
}

main () {
	if [[ "$1" = "-f" ]] ; then
		fetch_snapshot
		echo >&2
	fi

	genlist_snapshots
	echo >&2
	unpack_ebuilds
	echo >&2
	print_info
	echo >&2
	clean
}

if [[ "$#" -eq 1 ]] && [[ "$1" = "-f" ]] ; then
	fetch_snapshot
	echo >&2
	main
elif [[ "$#" -eq 0 ]] ; then
	main
else
	print_usage
fi

