#!/bin/sh -e
#
#    updates_available: calculate and cache the number of updates available
#    Copyright (C) 2008 Canonical Ltd.
#
#    Authors: Dustin Kirkland <kirkland@canonical.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, version 3 of the License.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

PKG="byobu"
DATA="$HOME/.$PKG"
color 2>/dev/null || color() { true; }

if [ "$1" = "--detail" -o "$1" = "--short" ]; then
	if which apt-get >/dev/null; then
		detail=`apt-get -s -o Debug::NoLocking=true upgrade`
		if [ "$1" = "--detail" ]; then
			printf "$detail"
		else
			short=`printf "$detail" | grep -c ^Inst`
			printf "$short"
		fi
	fi
	exit 0
fi

print_updates() {
	u=$1
	s=$2
	if [ -n "$u" ]; then
		if [ "$u" -gt 0 ]; then
			color b r W; printf "%d" "$u"; color -; color r W; printf "!"
			if [ -n "$s" ]; then
				if [ "$s" -gt 0 ]; then
					printf "!"
				fi
			fi
			color --
		fi
	fi
}

update_cache() {
	mycache=$1
	# Now we actually have to do hard computational work to calculate updates.
	# Let's try to be "nice" about it:
	renice 10 $$ >/dev/null 2>&1 || true
	ionice -c3 -p $$ >/dev/null 2>&1 || true
	# These are very computationally intensive processes.
	# Background this work, have it write to the cache files,
	# and let the next cache check pick up the results.
	if [ -x /usr/lib/update-notifier/apt-check ]; then
		# If apt-check binary exists, use it
		/usr/lib/update-notifier/apt-check 2>&1 | tail -n 1 | sed "s/;/ /" > $mycache &
	elif which apt-get >/dev/null; then
		# If apt-get exists, use it
		apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst > $mycache &
	elif which zypper >/dev/null; then
		# If zypper exists, use it
		zypper --no-refresh lu --best-effort | grep -c 'v |' > $mycache &
	elif which yum >/dev/null; then
		# If yum exists, use it
		# TODO: We need a better way of counting updates available from a RH expert
		yum list updates -q | grep -vc "Updated Packages" > $mycache &
	elif which pacman >/dev/null; then
		# If pacman (Archlinux) exists, use it
		LC_ALL=C pacman -Sup | grep -vc "^\(::\| \)" > $mycache &
	fi
}

# Checks if we need to update the cache.
# TODO: add more distro
update_needed() {
	mycache=$1
	# The cache doesn't exist: create it
	[ ! -e "$mycache" ] && return 0
	if which apt-get >/dev/null; then
		# Debian/ubuntu
		[ "/var/lib/apt" -nt "$mycache" ] || [ "/var/lib/apt/lists" -nt "$mycache" ]
		return $?
	elif which pacman >/dev/null; then
		# Archlinux
		for db in /var/lib/pacman/sync/*.db; do
			[ "$db" -nt "$mycache" ] && return 0
		done
		return 1
	fi
	return 1
}

[ -d "/var/run/screen/S-$USER" ] && DIR="/var/run/screen/S-$USER" || DIR="$DATA"
mycache="$DIR/$PKG.updates-available"

# If mycache is present, use it
[ -r $mycache ] && print_updates `grep "^[0-9]" $mycache | sed "s/ .*$//"`

# If we really need to do so (mycache doesn't exist, or the package database has changed),
# background an update now
update_needed "$mycache" && update_cache "$mycache"
