#!/bin/sh
# *******************************************************************
# **  @file eisman_download.sh - download package
# **
# **  Creation:     2013-01-13 dv
# **  Last update:  $Id: eisman_download.sh 42826 2016-08-13 19:44:23Z 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

UNLIMITED="9999"


# *******************************************************************
# **  parse wget output to display a simple progress bar. Receives
# **  wget output on stdin
# **  @param  n/a
# **  @return n/a
# *******************************************************************

wget_progress_bar()
{
    local flag=2
    local c
    local count=0

    while read -d '' -rn 1 c
    do
        if [ "${flag}" -eq 2 ]
        then
            if [ "${c}" = '[' ]
            then
                flag=1
                if [ ${count} -gt 0 ]
                then
                    echo -en "\033[${count}D"
                fi
                count=0
            fi
        elif [ "${flag}" -eq 1 ]
        then
            if [ "${c}" = ']' ]
            then
                flag=2
            elif [ "${c}" = '=' ] || [ "${c}" = '>' ]
            then
                echo -n "#"
                count=$((${count} + 1))
            fi
        fi
    done
}


# *******************************************************************
# **  use grep to perform a query upon the package.db file.
# **  @param  $1  package
# **  @param  $2  version (can be an empty string!)
# **  @param  $3  status  (may be stable or something else)
# **  @param  $4  url to select package from
# **  @param  $5  the info field to be returned
# **  @return (on stdout) data found in packages.db meeting the
# **          search criteria
# *******************************************************************

query_package_db()
{
    local package="${1}"
    local version="${2}"
    local status="${3}"
    local urlfilter="${4}/dummy"
    local field="${5}"
    local maxresults="${6}"
    local header=$((${FIELDHEADER} + 1))

    if [ -z "$version" ]
    then
        version='.*'
    fi

    if [ "${status}" = "stable" ]
    then
        status='s'
    else
        status='u'
    fi

    urlfilter="$(echo    "${urlfilter}"    | cut -d '?' -f 1)"
    urlfilter="$(dirname "${urlfilter}"    | sed 's|/[0-9]*$||')"
    urlfilter="$(echo    "${urlfilter}.*"  | sed 's|\?|\\?|g')"

    if [ "${maxresults}" -eq "${UNLIMITED}" ]
    then
        grep -E "^\[.*\]\[${package}\]\[${version}\]\[${status}\]\[${urlfilter}.*\]${field} " \
             "${EISMAN_PATH}/packages.db" |
        cut  -d ']' -f 6                  |
        cut  -c "${header}-"
    else
        grep -E "^\[.*\]\[${package}\]\[${version}\]\[${status}\]\[${urlfilter}.*\]${field} " \
             "${EISMAN_PATH}/packages.db" |
        cut  -d ']' -f 6                  |
        cut  -c "${header}-"              |
        head -n "${maxresults}"
    fi
}


# *******************************************************************
# ** main program
# *******************************************************************
main()
{
    # read parameters
    if [ "$#" = 4 ]
    then
        PACKAGE="$1"
        VERSION="$2"
        STATUS="$3"
        URL="$4"
    else
        echo 'error: invalid number of arguments!' >&2
        echo 'usage: eisman_download <package> <version> <url>' >&2
        exit 1
    fi

    # download ony if not already in cache
    if [ ! -d "${EISMAN_PATH}/cache/${PACKAGE}/${VERSION}" ]
    then
        local printline="${PACKAGE} (${VERSION})..."
        local length=$((${#printline} + 22))

        echo -en "=> [                    ] ${printline}"
        echo -en "\033[${length}D"

        success=0

        # resolve url
        url=$(query_package_db "${PACKAGE}" "${VERSION}" "${STATUS}" "${URL}" 'url' '1')
        if [ -z "$url" ]
        then
            # this should never happen if called automatically
            echo "   error: unable to get URL for ${PACKAGE}" >&2
        else
            # download file into temporary location
            rm -f /tmp/tmpinfofile$$

            # execute wget to download the package and pass stdout of wget over
            # to wget_progress_bar, to show a simple progress bar.
            # Do some pipe redirection to fetch exit code of wget.
            # see: http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another
            (
                (
                    (
                        (
                            /usr/local/bin/wget.sh     \
                                -O /tmp/tmpinfofile$$  \
                                --progress=bar:force "${url}" 2>&1; echo $? >&3
                        ) |
                        wget_progress_bar >&4
                    ) 3>&1
                ) |
                (read xs; exit $xs)
            ) 4>&1

            if [ "$?" = "0" ]
            then
                # check for multible sha${chk_value}sum
                for chk_value in 1 256
                do
                    # check sha${chk_value}sum if given in info file
                    chksum=$(query_package_db "${PACKAGE}" "${VERSION}" "${STATUS}" "${URL}" "sha${chk_value}sum" '1')
                    if [ -n "${chksum}" ]
                    then
                        have_chksum=true
                        break
                    fi
                done

                if ${have_chksum:-false}
                then
                    # package has sha${chk_value}sum -> check
                    tmpsum=$(sha${chk_value}sum -b /tmp/tmpinfofile$$)
                    tmpsum=${tmpsum%% *}

                    if [ "$tmpsum" = "$chksum" ]
                    then
                        success=1
                    else
                        echo "error: ${PACKAGE} has invalid sha${chk_value}sum" >&2
                    fi
                else
                    # no sha${chk_value}sum -> don't check
                    success=1
                fi

                # if successful copy to real destination
                if [ "$success" = "1" ]
                then
                    mkdir -p "${EISMAN_PATH}/cache/${PACKAGE}/${VERSION}"
                    cp /tmp/tmpinfofile$$ \
                        "${EISMAN_PATH}/cache/${PACKAGE}/${VERSION}/$(basename $url)"
                    if [ "$?" != "0" ]
                    then
                        success=0
                        echo "error: copy to package cache failed" >&2
                    fi
                fi
            else
                echo "error: failed to download package \"${PACKAGE}\"" >&2
            fi

            # remove temporary file
            rm -f /tmp/tmpinfofile$$
        fi

        # show success
        if [ "$success" = 1 ]
        then
            echo
            mecho --ok
        else
            echo
            mecho --fail
            exit 1
        fi
    fi

    exit 0
}

main "${@}"
