#!/bin/bash
#
# Adapted from freepops-updater-dialog
# Massimiliano Adamo <maxadamo@gmail.com>

#set -x
#set -e

# the return value of functions
RC=""


# XXX should be written at config time
PROC=`basename $0`
CORE=${CORE:-`which freepopsd`}
FREEPOPS="$CORE -e updater.lua php"
PREAMBLE="zenity --window-icon=/usr/share/pixmaps/freepops-updater-zenity.svg"
GAUGE='--progress --text=%s --auto-close'
MESSAGE="--info --title %s --text=%s"
CHECKLIST="--list --checklist --print-column=2 --column= --column=name --column=description --text=%s" 
TEXTINFO="--text-info --width=600 --height=400 --filename"
WARNING="--warning --title=Error --text"
MKTEMP="$(which tempfile >/dev/null 2>/dev/null && echo tempfile || echo mktemp)"

# command line argument parsing ##############################################

function parse_args() {
  if [ $# -ge 1 ]; then
    echo -e "\nUsage: $PROC\n\nRun the command without any option\n"
    exit 1
  fi
}

# tempfile handling, with garbage collection #################################
TODELETE=`$MKTEMP`

function erase_tmp_files() {
  rm -f `cat $TODELETE` $TODELETE
}

function mk_temp(){
  local tmp=`$MKTEMP`
  echo $tmp >> $TODELETE
  echo $tmp
}

trap erase_tmp_files EXIT SIGTERM SIGCHLD

# widgets ###################################################################

# text : string 
# items : file which lines are 'name desciption on/off'
# RC: file which lines are name
function checklist() {
	local text="$1"
	local items="$2"

	local CMD=`mk_temp`
	echo -n $PREAMBLE > $CMD
	printf -- " $CHECKLIST " "$text"  >> $CMD
	cat $items >> $CMD

	/bin/bash $CMD
}

# title, message : string
function message(){
	local title="$1"
	local message="$2"
	local CMD=`mk_temp`

	echo -n $PREAMBLE > $CMD
	printf -- " $MESSAGE " "$title" "$message" >> $CMD
	/bin/bash $CMD
}

# helper to access the metadata of a plugin ##################################
function field(){
	local data=$1
	local name=$2

	grep "^$2" $1 | sed "s/^$2 *: *//"
}

# the main has you ###########################################################
function main(){
parse_args "$@"
local AWK=`mk_temp`
cat > $AWK <<EOT
BEGIN { RS = "\n\n+"; FS = "\n"; }
{ 
  cmd = "mktemp -t tmp.freepops." NR ".XXXXXXXX";
  RS = "\n"; 
  cmd | getline tmp; 
  RS = "\n\n+"; 
  print \$0 > tmp; 
  print tmp; 
}
EOT
local ERR=`mk_temp`
exec 3> >($PREAMBLE --progress --pulsate --auto-close --text="Downloading Metadata...")
echo . >&3
FILES=`$FREEPOPS fetch_modules_metadata 2>$ERR | awk -f $AWK`
# Cannot use exit status of above command because of pipe and variable declaration
exec 3>&-
ARRAY=( $FILES )
if [ ${#ARRAY[@]} -le 1 ]; then
	$PREAMBLE $WARNING='Error fetching metadata!'
	$PREAMBLE $TEXTINFO=${ARRAY[0]} --title="Error fetching metadata"
	exit 1
fi
# register temp files to the garbage collector
echo $FILES >> $TODELETE
N=`echo $FILES | wc -w `
local I=0
local perc=0
local CMD=`mk_temp`
local FAILED=`mk_temp`
local CHECKLIST_INPUT=`mk_temp`
echo -n $PREAMBLE > $CMD
printf -- " $GAUGE " "'Checking for updates...'" >> $CMD
(for METADATA in $FILES; do
	((perc=$I \* 100 / $N))
	echo $perc
	local M=`field $METADATA module_name`
	local VREQ=`field $METADATA require_version`
	local VLOC=`field $METADATA local_version`
	local VUPS=`field $METADATA version`
	local URL=`field $METADATA url`
	local SHOULD=`field $METADATA should_update`
	local CAN=`field $METADATA can_update`
	local WHY=`field $METADATA why_cannot_update`
	if [ "$CAN" = "true" ]; then
		if [ "$SHOULD" = "true" ]; then
			echo -n TRUE $M "'$VLOC -> $VUPS'" ' ' >> $CHECKLIST_INPUT
		else
			M=$M
		fi
	else	
		if [ "$SHOULD" = "true" ]; then
			echo -n "$M: $WHY\n" >> $FAILED
		else
			M=$M
		fi
	fi
	((I=I+1))
done) | /bin/bash $CMD

if [ -s $CHECKLIST_INPUT ]; then
	local SELECTED=`mk_temp`
	checklist "'Select the plugins to update.'" $CHECKLIST_INPUT > $SELECTED
	if [ $? != 0 ]; then
		$PREAMBLE $WARNING='Update canceled by user'
		exit 1
	fi

	local DOWNERR=`mk_temp`
	for X in `cat $SELECTED|tr '|' ' '`; do
		exec 3> >($PREAMBLE --progress --pulsate --auto-close --text="Downloading '$X'")
		echo . >&3
		# Fetch command prints out a blank line and will be stripped with sed.
		$FREEPOPS fetch_module $X 'true'|sed -e /^$/d >> $DOWNERR 2>&1
		exec 3>&-
	done

	if [ -s $DOWNERR ]; then
		$PREAMBLE $WARNING='Error fetching one\nor more modules!'
		$PREAMBLE $TEXTINFO=$DOWNERR --title="Error fetching module(s)"
	else
		$PREAMBLE --info --title="FreePOPs Updater" --text='Update completed succesfully!'
	fi
else
	message "'No updates available'" "'    Nothing to update!    '"
fi

if [ -s $FAILED ]; then
	message "'Some modules cannot be updated!'" "'`cat $FAILED`'"
fi

}

# here we go! ###############################################################
if [ -z $DISPLAY ]; then
  echo -e "\nSet your DISPLAY or use freepops-updater-dialog instead\n"
  exit 1
fi
if [ -z `which zenity 2>/dev/null` ]; then
	IFS=
	MESSAGE="'zenity' utility not found.
Please install the zenity package."
	if [ -z `which xmessage 2>/dev/null` ]; then
		echo $MESSAGE
		exit 1
	else
		xmessage -center $MESSAGE
		exit 1
	fi
fi
if [ ! -x $CORE ]; then
	$PREAMBLE $WARNING="freepopsd not found"
	exit 1
fi
if  [ `id -u` -ne 0 ]; then
	$PREAMBLE $WARNING="$PROC must be run as root"
	exit 1
fi

main "$@"

# eof
