#!/bin/sh
# *******************************************************************
# **  @file eisman_find_upgradables.sh - find list of upgradable packages
# **
# **  Creation:     2016-07-23 dv
# **  Last update:  $Id: eisman_find_upgradables.sh 43396 2016-09-18 16:29:34Z hbfl $
# **
# **  Copyright (c) 2013-2017 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))

    query_package_db  \
        ""            \
        ""            \
        ""            \
        ""            \
        ""            \
        ""            \
        "name"        \
        "${EISMAN_PATH}/installed.db"             |
            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))

    query_package_db       \
        ""                 \
        ""                 \
        "${packages}"      \
        ""                 \
        ""                 \
        ""                 \
        "${fields}|------" \
        "${EISMAN_PATH}/installed.db"             |
            cut  -c "${header}-"                  |
            sed ':a;N;$!ba;s/\n/|/g;s/|-[-]*/\n/g;s/\n|/\n/g' |
            sort
}


# *******************************************************************
# **  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  state of packages "s" if stable only, "" otherwise
# **  @return n/a
# *******************************************************************

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

    query_package_db       \
        ""                 \
        ""                 \
        "${packages}"      \
        ""                 \
        "${state}"         \
        ""                 \
        "${fields}|------" \
        "${EISMAN_PATH}/packages.db"              |
            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
        local eiskernel_dev=false

        # check if eiskernel-dev package is installed
        if echo "${PACKAGES}" | grep -q 'eiskernel-dev'
        then
            eiskernel_dev=true
        fi

        # 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) }')"

        # if there was an eiskernel-dev package installed
        # readd this entry
        if ${eiskernel_dev}
        then
             PACKAGES="${PACKAGES}|eiskernel-dev"
        fi
    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}" "")
    else
        AVAILABLE=$(query_available_packages "name|version" "${PACKAGES}" "s")
    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 "${@}"
