#!/bin/sh
#
# pkgdb - module of the SliTaz Cook
# Copyright (C) SliTaz GNU/Linux - GNU GPL v3
#

. /usr/lib/slitaz/libcook.sh


#
# Functions
#

dblog() { tee -a $LOGS/pkgdb.log; }


# Return size of file in human readible format
# Note, "du" in opposite returns size occupied by file on disk (4KB multiple in most cases)

filesize() { busybox ls -lh "$1" | awk '{print $5 "B"}'; }





# Create suitable packages list for TazPkg and only for built packages
# as well as flavors files for TazLiTo. We don't need logs since we do it
# manually to ensure everything is fine before syncing the mirror.

rm $LOGS/pkgdb.log 2>/dev/null

case "$1" in
	--flavors|--rmpkg) ;;
	*)
		[ -n "$1" ] && PKGS="$1"
		if [ ! -d "$PKGS" ]; then
			{ newline; _ "Packages directory \"%s\" doesn't exist" "$PKGS"; newline; } | dblog
			exit 1
		fi ;;
esac

time=$(date +%s)
flavors="$SLITAZ/flavors"
live="$SLITAZ/live"

echo 'cook:pkgdb' > $command
_ 'Cook pkgdb: Creating all packages lists' | log
newline; { _ 'Creating lists for "%s"' "$PKGS"; separator; } | dblog

{ _ 'Cook pkgdb started: %s' "$(date "$(_ '+%%F %%R')")"; newline; } | dblog

cd $PKGS
rm -f packages.* extra.list
touch packages.equiv

_n 'Creating file "%s"' 'packages.list' | dblog
ls -1 *.tazpkg | sed s'/.tazpkg//' > $PKGS/packages.list
echo " ($(filesize $PKGS/packages.list))" | dblog

_n 'Creating file "%s"' 'packages.md5' | dblog
md5sum *.tazpkg > $PKGS/packages.md5
echo " ($(filesize $PKGS/packages.md5))" | dblog
cp $PKGS/packages.md5 $PKGS/packages.toremove			# list of unnecessary packages

md5sum packages.md5 | cut -d' ' -f1 > ID
( cat ./ID | tr $'\n' ' '; date -ur ./ID +%s ) > IDs	# md5 and timestamp

_n 'Creating file "%s"' 'descriptions.txt' | dblog
rm $PKGS/descriptions.txt 2>/dev/null
for i in $(ls $WOK | sort); do
	if [ -e "$WOK/$i/description.txt" ]; then
		echo "$i" >> descriptions.txt
		cat "$WOK/$i/description.txt" | sed 's|^$| |' >> descriptions.txt
		echo >> descriptions.txt
	fi
done
echo " ($(filesize $PKGS/descriptions.txt))" | dblog


_ 'Creating lists from "%s"' "$WOK" | dblog
cd $WOK
for pkg in *; do
	unset_receipt
	. $pkg/receipt
	# PACKED_SIZE and UNPACKED_SIZE are only in built receipt
	[ -s $pkg/taz/*/receipt ] && . $pkg/taz/*/receipt

	if [ -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" ] || \
	   [ -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg" ]; then

		# packages.desc lets us search easily in DB
		cat >> $PKGS/packages.desc <<EOT
$PACKAGE | $VERSION$EXTRAVERSION | $SHORT_DESC | $CATEGORY | $WEB_SITE
EOT

		# packages.txt used by tazpkg and tazpkg-web also to provide
		# a human readable package list with version and description.
		cat >> $PKGS/packages.txt <<EOT
$PACKAGE
$VERSION$EXTRAVERSION
$SHORT_DESC
$PACKED_SIZE ($UNPACKED_SIZE installed)

EOT

		# packages.info combines TazPkg separate files
		# and will substitute them all
		SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
		DEPENDS=$(echo $DEPENDS) # remove newlines from some receipts
		MD5="$(fgrep " $PACKAGE-$VERSION$EXTRAVERSION.tazpkg" $PKGS/packages.md5 | awk '{print $1}')"
		cat >> $PKGS/packages.info <<EOT
$PACKAGE	$VERSION$EXTRAVERSION	$CATEGORY	$SHORT_DESC	$WEB_SITE	$TAGS	$SIZES	$DEPENDS	$MD5
EOT

		# packages.equiv is used by tazpkg install to check depends.
		for i in $PROVIDE; do
			DEST=''
			echo $i | fgrep -q : && DEST="${i#*:}:"
			if grep -qs ^${i%:*}= $PKGS/packages.equiv; then
				sed -i "s/^${i%:*}=/${i%:*}=$DEST$PACKAGE /" \
					$PKGS/packages.equiv
			else
				echo "${i%:*}=$DEST$PACKAGE" >> $PKGS/packages.equiv
			fi
		done

		# files.list provides a list of all packages files.
		cat $pkg/taz/*/files.list | sed s/^/"$pkg: \0"/ >> \
			$PKGS/files.list

		# list of unnecessary packages
		sed -i "/ $PACKAGE-$VERSION$EXTRAVERSION.tazpkg/d" $PKGS/packages.toremove
	else
		# if receipt variable HOST_ARCH absent/empty or contains ARCH
		if [ -z "$HOST_ARCH" -o "${HOST_ARCH/$ARCH/}" != "$HOST_ARCH" ]; then
			_ '  - absent: %s (%s)' "$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$ARCH" | dblog
		fi
	fi
done

# Display list size.
_ 'Done: %s (%s)' 'packages.desc'  "$(filesize $PKGS/packages.desc)"  | dblog
_ 'Done: %s (%s)' 'packages.txt'   "$(filesize $PKGS/packages.txt)"   | dblog
_ 'Done: %s (%s)' 'packages.info'  "$(filesize $PKGS/packages.info)"  | dblog
_ 'Done: %s (%s)' 'packages.equiv' "$(filesize $PKGS/packages.equiv)" | dblog

cd $PKGS


# Check for unnecessary packages
if [ -s "$PKGS/packages.toremove" ]; then
	newline | dblog
	case x$rmpkg in
		x) _ 'Found unnecessary packages (use `cook pkgdb --rmpkg` to remove):' | dblog;;
		*) _ 'Removing unnecessary packages:' | dblog;;
	esac
	while read pkgsum pkgfile; do
		echo "  - $pkgfile" | dblog
		sed -i "/${pkgfile%.tazpkg}/d" $PKGS/packages.list
		sed -i "/ $pkgfile/d" $PKGS/packages.md5
		[ -n "$rmpkg" ] && rm $PKGS/$pkgfile	# remove packages only with --rmpkg
	done < $PKGS/packages.toremove
	newline | dblog
fi
rm $PKGS/packages.toremove


# files.list.lzma
_n 'Creating file "%s"' 'files.list.lzma' | dblog
touch files.list
# pkgs.slitaz.org strongly depends on list sorted by packages names
lzma e files.list files.list.lzma
echo " ($(filesize $PKGS/files.list.lzma))" | dblog

# Pre-sorting filenames causes 10% smaller resulting lzma file
_n 'Creating file "%s"' 'files-list.lzma' | dblog
cat files.list | sort -k2 -o files.list.sorted
lzma e files.list.sorted files-list.lzma
rm -f files.list files.list.sorted
echo " ($(filesize $PKGS/files-list.lzma))" | dblog

[ -e files.list.md5 ] && rm files.list.md5
md5sum files-list.lzma | cut -d' ' -f1 | tr -d $'\n' > files-list.md5

# Make bundle to fast recharge
_n 'Creating file "%s"' 'bundle.tar.lzma' | dblog
[ -f bundle.tar.lzma ] && rm bundle.tar.lzma
# Make sure to get "mirrors" file
until [ -e 'mirrors' ]; do
	wget -q http://mirror1.slitaz.org/mirrors
	echo -n '.' | dblog; sleep 5
done
# Make sure to get "extra.list" file
until [ -e 'extra.list' ]; do
	wget -q -O extra.list http://mirror1.slitaz.org/packages/get.list
	echo -n '.' | dblog; sleep 5
done
busybox tar -chaf bundle.tar.lzma \
	mirrors extra.list files-list.md5 packages.info descriptions.txt \
	packages.desc packages.md5 packages.txt packages.list packages.equiv
rm ./mirrors
echo " ($(filesize $PKGS/bundle.tar.lzma))" | dblog

# Display some info.
separator | dblog
nb=$(ls $PKGS/*.tazpkg | wc -l)
time=$(($(date +%s) - $time))
# L10n: 's' is for seconds (cooking time)
{ _ 'Packages: %s - Time: %ss' "$nb" "$time"; newline; } | dblog


# Create all flavors files at once. Do we really need code to monitor
# flavors changes? Let's just build them with packages lists before
# syncing the mirror.
[ "$1" != '--flavors' ] && exit 1

if [ ! -d "$flavors" ]; then
	{ _ 'Missing flavors folder "%s"' "$flavors"; newline; } | dblog
	exit 1
fi

[ ! -d "$live" ] && mkdir -p $live
_ 'Creating flavors files in "%s"' "$live" | dblog
_ 'Cook pkgdb: Creating all flavors' | log
separator | dblog

_ 'Recharging lists to use latest packages...' | dblog
tazpkg recharge >/dev/null 2>/dev/null

# We need a custom tazlito config to set working dir to /home/slitaz.
if [ ! -f "$live/tazlito.conf" ]; then
	_ 'Creating configuration file "%s"' 'tazlito.conf' | dblog
	cp /etc/tazlito/tazlito.conf $live
	sed -i s@WORK_DIR=.*@WORK_DIR=\"/home/slitaz\"@ \
		$live/tazlito.conf
fi

# Update Hg flavors repo and pack.
if [ -d "$flavors/.hg" ]; then
	cd $flavors; hg pull -u
fi

cd $live
_ 'Starting to generate flavors...' | dblog
rm -f flavors.list *.flavor
for i in $flavors/*; do
	fl=$(basename $i)
	_ 'Packing flavor "%s"' "$fl" | dblog
	tazlito pack-flavor $fl >/dev/null || exit 1
	tazlito show-flavor $fl --brief --noheader 2>/dev/null >> flavors.list
done
cp -f $live/*.flavor $live/flavors.list $PKGS
separator | dblog
{ _ 'Total flavors size: %s' "$(du -sh $live | awk '{print $1}')"; newline; } | dblog
separator | dblog
_ 'Cook pkgdb end: %s' "$(date "$(_ '+%%F %%R')")" | dblog

> $command


exit 0
