#!/bin/bash
# by Spina <spina80@freemail.it>

function _get_pack_name
{
    local pack_name=${1##*/};
    local array=($(echo $pack_name | tr -s '-' ' '));
    local array_size=${#array[@]};
    pack_name=$(i=0; while (( $i < $array_size-3 )); do echo -n ${array[$i]}"-"; let i++; done);
    pack_name=${pack_name%-};
    echo $pack_name;
}

function _check_ext_program
{
    local ext_prog=(bunzip2 grep mktemp rm sed tr);
    local prog;
    local error=0;
    
    for prog in ${ext_prog[@]}; do
	if ! which $prog >& /dev/null; then 
	    echo "$prog: not found. I need it.";
	    error=1;
	fi
    done  
    
    (( $error == 1 )) && exit 1;
}

function _help
{
    echo -e "Use: ${0##*/} [-h|-n|-m|-v] [root_directory]\n\
For every package in ROOT_DIRECTORY/var/log/packages this script\n\
searches a corresponding package in the file ./MANIFEST.bz2 and\n\
prints out the name of the package on the standard output if it needs\n\
an upgrade.\n\n\
   -h\tprint this help and exits\n\
   -n\tprint the name of packages that don't need an upgrade\n\
   -m\tprint the name of packages which are missing in ./MANIFEST.bz2 or\n\
     \tfiltered by ~/.analyze_SlackPkg file\n\
   -v\tshow also current version of package\n\n\
ROOT_DIRECTORY is / by default, or the value of ROOT enviroment variable,\n\
or the value of root_directory passed in command line. If both variable ROOT\n\
and root_directory are set, root_directory is used."
}

_check_ext_program;

FILTER_FILE=~/.analyze_SlackPkg;
FLAG_FILTER=0;
[ -f $FILTER_FILE ] && FLAG_FILTER=1;

FLAG_N=0;
FLAG_M=0;
FLAG_V=0;

while getopts hnmv OPT; do
    case $OPT in
	h)
	    _help;
	    exit 0;
	    ;;
	n)
	    FLAG_N=1;
	    ;;
	m)  FLAG_M=1;
	    ;;
	v)  FLAG_V=1;
	    ;;
	?)
	    exit 3;
	    ;;
    esac
done

if (( ${FLAG_N} + ${FLAG_M} + ${FLAG_V} > 1 )) ; then
    echo "Only one option between -n, -m and -v must be set";
    exit 4;
fi

while (( $OPTIND != 1 )); do
    shift;
    let OPTIND--;
done

[ ! -f "MANIFEST.bz2" ] &&\
    echo "MANIFEST.bz2 not found in current directory,"\
    "please enter in the directory where is located MANIFEST.bz2" &&\
    exit 2;

root=$1;
root=${root:-$ROOT};
root=${root%/};
root=${root}/var/log/packages/;

[ ! -d $root ] && \
    echo "$root not found, $1 is not the root directory" &&\
    exit 5;

if [ -d /tmp/tmp ]; then
    TMP_DIR=/tmp/tmp;
else
    TMP_DIR=/tmp;
fi

TMP_FILE=$(mktemp -p $TMP_DIR packages.XXXXXX);
bunzip2 -c MANIFEST.bz2 | sed -n /Package:/'{s/.*\(\.\/.*\)/\1/;p;}' > $TMP_FILE;

for file in ${root}*; do 
    FILTERED=0;
    pack_name=$(_get_pack_name $file);
    prob_pack=($(grep "/$pack_name-" $TMP_FILE));
    
    case ${#prob_pack[@]} in
	0)
	    pack="";
	    ;;
	1)
	    pack=${prob_pack[0]};
	    ;;
	*) 
	    pack="";
	    for package in ${prob_pack[@]}; do
		if [[ $(_get_pack_name $package) == $pack_name ]]; then
		    pack=$package;
		    break
		fi
	    done
	    ;;
    esac

    if [[ $pack != "" ]] && (( $FLAG_FILTER )) && grep "${pack_name}$" $FILTER_FILE >&/dev/null; then
        FILTERED=1;
	pack="";
    fi
    
    if (( FLAG_N == 1 )); then
	if [[ $pack != "" ]] && [[ ${pack##*/} == ${file##*/}.t?z ]]; then
	    echo ${file##*/};
	fi
    elif (( FLAG_M == 1 )); then
	if [[ $pack == "" ]] && (( $FILTERED == 0 )); then
	    echo ${file##*/};
        elif [[ $pack == "" ]] && (( $FILTERED == 1 )); then
            echo -e "${file##*/} \033[32;1mfiltered by \033[33;1m${FILTER_FILE}\033[0m";
        fi
    else
	if [[ $pack != "" ]] && [[ ${pack##*/} != ${file##*/}.t?z ]]; then
            if (( FLAG_V == 1 )); then
		echo -e "$pack \033[32;1mthe current version is \033[33;1m${file##*/}\033[0m";
            else
                echo "$pack";
	    fi
	fi
    fi
done

rm -f $TMP_FILE;
exit 0;
