#!/bin/sh
# *******************************************************************
# **  @file eisman_find_upgradables.sh - find list of upgradable packages
# **
# **  Creation:     2016-07-23 dv
# **  Last update:  $Id: eisman_find_upgradables.sh 42738 2016-07-28 14:45:52Z hbfl $
# **
# **  Copyright (c) 2013-2016 the eisfair team, team(at)eisfair(dot)org
# **
# **  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; either version 2 of the License, or
# **  (at your option) any later version.
# *******************************************************************

. /var/install/include/eislib
. /var/install/include/eismanlib


# *******************************************************************
# **  read all installed packages and convert them into a
# **  single string
# **  @param  $1  fields to query
# **  @param  $2  optional package names
# **  @return n/a
# *******************************************************************

query_installed_package_list()
{
    local header=$((${FIELDHEADER} + 1))

    ${EISMAN_BIN_PATH}/eisman_query.sh --installed --unstable --fields="name" |
    cut  -c "${header}-"                          |
    sed ':a;N;$!ba;s/\n/|/g;s/|-[-]*//g'
}


# *******************************************************************
# **  read a list of packages from the installed packages database and
# **  reformat the result, so that every package is printed in a single
# **  line
# **  @param  $1  fields to query
# **  @param  $2  list of package names
# **  @return n/a
# *******************************************************************

query_installed_packages()
{
    local fields=${1}
    local packages=${2}
    local header=$((${FIELDHEADER} + 1))

    ${EISMAN_BIN_PATH}/eisman_query.sh --installed --unstable --fields="${fields}" "${packages}" |
    cut  -c "${header}-"                          |
    sed ':a;N;$!ba;s/\n/|/g;s/|-[-]*/\n/g;s/\n|/\n/g'
}


# *******************************************************************
# **  read a list of packages from the available packages database and
# **  reformat the result, so that every package is printed in a single
# **  line
# **  @param  $1  fields to query
# **  @param  $2  list of package names
# **  @param  $3  --unstable if unstable is allowed "" otherwise
# **  @return n/a
# *******************************************************************

query_available_packages()
{
    local fields=${1}
    local packages=${2}
    local unstable=${3}
    local header=$((${FIELDHEADER} + 1))

    ${EISMAN_BIN_PATH}/eisman_query.sh ${unstable} --fields="${fields}" "${packages}" |
    cut  -c "${header}-"                          |
    sed ':a;N;$!ba;s/\n/|/g;s/|-[-]*/\n/g;s/\n|/\n/g'
}


# *******************************************************************
# **  read list of installed packages. Only names in a single line
# **  divided by '|'
# **  @param  n/a
# **  @return n/a
# *******************************************************************

read_installed_list()
{
    PACKAGES=$(query_installed_package_list)

    if echo "${PACKAGES}" | grep -q 'eiskernel'
    then
        # remove all kernel names
        PACKAGES=$(echo "${PACKAGES}"              |
           sed -e 's#eiskernel[-a-z]*|##g')

        # add running kernel
        PACKAGES="${PACKAGES}|eiskernel-$(uname -r |
           awk -F'-' '{ print tolower($NF) }')"
    fi

    INSTALLEDLIST=$(query_installed_packages "name,version" "(${PACKAGES})")
}


# *******************************************************************
# **  read list of packages from package database that corresponds
# **  with the list of installed packages
# **  @param  $1  unstable "yes" | "no"
# **  @return n/a
# *******************************************************************

query_package_database()
{
    if [ "${1}" = "yes" ]
    then
        AVAILABLE=$(query_available_packages "name,version" "(${PACKAGES})" "--unstable")
    else
        AVAILABLE=$(query_available_packages "name,version" "(${PACKAGES})" "")
    fi
}


# *******************************************************************
# **  compare list of installed packages with the list of available
# **  packages from the package database. If newer versions could be
# **  found, they are written to to list of installed packages
# **  @param  n/a
# **  @return n/a
# *******************************************************************

associate_packages()
{
    local OLDIFS=IFS
    local line

    IFS="
"
    for line in ${INSTALLEDLIST}
    do
        local package="$(echo ${line} | cut -d '|' -f 1)"
        local version="$(echo ${line} | cut -d '|' -f 2)"
        local bestver="${version}"

        if [ -n "${package}" ]
        then
            local updates=$(echo "${AVAILABLE}" | grep -E "^${package}\|")

            if [ -n "${updates}" ]
            then
                for update in ${updates}
                do
                    local ver="$(echo ${update} | cut -d '|' -f 2)"
                    local res="$(diff_version "${ver}" "${bestver}" )"

                    if [ "${res}" = "new" ]
                    then
                        bestver="${ver}"
                    fi
                done

                if [ "$(diff_version "${bestver}" "${version}")" = "new" ]
                then
                    UPDATELIST="${UPDATELIST} ${package}=${bestver}"
                fi
            fi
        fi
    done

    IFS=${OLDIFS}
}


# *******************************************************************
# **  main routine
# **  @param  $@ list of command line arguments
# **  @return n/a
# *******************************************************************

unstable="no"

main()
{
    while [ "${1:0:2}" = "--" ]
    do
        case $1 in
        --unstable)
            shift
            unstable="yes"
            ;;
        *)
            echo "error: unknown option \"$1\"!" >&2
            echo ""
            return 1
            ;;
        esac
    done

    # read list of installed packages
    read_installed_list

    # check package database for corresponding entries
    query_package_database "${unstable}"

    # compare versions of installed packages with available ones
    associate_packages

    # output results to stdout
    echo "${UPDATELIST}"

    exit 0
}

main "${@}"
