#!/bin/bash
# *******************************************************************
# **  @file eisman_uninstall_r.sh - uninstall package (intermediate)
# **
# **  Creation:     2013-01-13 dv
# **  Last update:  $Id: eisman_uninstall_r.sh 44252 2016-12-30 23:14:30Z dv $
# **
# **  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


# *******************************************************************
# **  show help on arguments and possible options
# **  @param  n/a
# **  @return n/a
# *******************************************************************

show_help()
{
cat <<EOF

Uninstall an eisfair package

usage:
    eisman uninstall [OPTIONS] PACKAGE

options:
    --help          show this help screen
    --force         uninstall even if requirements deny it
    --auto          non interactive mode
    --recursive     uninstall all requirements too (EXPERIMENTAL)
    --no-wait-anim  do not show wait animation
    --output=<file> redirect result into a file
    --info          do not uninstall, only show packages

EOF
}


# *******************************************************************
# **  list the packages returned by eisman_tree to show all
# **  requirements prior to installation
# **  @param  $1  list of packages
# **  @return n/a
# *******************************************************************

list_packages()
{
    local packages="${1}"
    local count
    local line

    # show table header if not in auto mode
    if [ "${auto}" = "no" ]
    then
        echo " "
        echo "The following packages will be uninstalled:"
        echo " "
        echo "version  status   name              source"
        echo "---------------------------------------------------------"
    fi

    # redefine separator
    IFS_BAK=${IFS}
    IFS="
"

    # split package list into lines
    count=0
    for line in ${packages}
    do
        # if this is the space entry remember it's value
        # otherwise print the line onto the screen
        if [ "${line:0:8}" = "space = " ]
        then
            space=${line:8}
        elif [ "${line:0:8}" = "warning:" ]
        then
            mecho --warn "${line}"
        else
            if [ "${auto}" = "no" ]
            then
                if [ "${#line}" -gt 72 ]
                then
                    echo "${line:0:72}..."
                else
                    echo "${line}"
                fi
            fi
            count=$((${count} + 1))
        fi
    done

    # restore separator
    IFS=${IFS_BAK}

    # show statistics (number of packages and disk space)
    if [ "${auto}" = "no" ]
    then
        echo " "
        echo "${count} package(s) will free approx. ${space} MB of disk space."
        echo " "
    fi
}


# *******************************************************************
# **  install the list of packages one by one following the precise
# **  order returned by eisman_tree.sh
# **  @param  $1  list of packages
# **  @return n/a
# *******************************************************************

uninstall_packages()
{
    local packages="${1}"

    IFS_BAK=${IFS}
    IFS="
"

    for line in ${packages}
    do
        if [ "${line:0:8}" != "space = " ]
        then
            local version=""
            local package=""
            local token
            local filename
            local idx=0

            IFS=" "
            for token in ${line}
            do
                case ${idx} in
                0)
                    version="${token}"
                    ;;
                2)
                    package="${token}"
                    ;;
                3)
                    url="${token}"
                    ;;
                esac
                idx=$((${idx} + 1))
            done
            IFS="
"
            if [ "${quiet}" = "no" ]
            then
                mecho --info -n "Uninstallation of: "
                mecho "${package} (${version}) ..."

                if ! ${EISMAN_BIN_PATH}/eisman_uninstall.sh --auto "${package}"
                then
                    IFS=${IFS_BAK}
                    exit 1
                fi
            else
                if ! ${EISMAN_BIN_PATH}/eisman_uninstall.sh --quiet --auto "${package}"
                then
                    IFS=${IFS_BAK}
                    exit 1
                fi
            fi
        fi
    done

    IFS=${IFS_BAK}
}


# *******************************************************************
# **  resolve list of packages that can be uninstalled because of
# **  beeing no longer required by other packages. Then trigger
# **  uninstallation of the result list
# **  @param  $1  info only, do not uninstall if "yes"
# **  @param  $2  do not ask for acknowledges if "yes"
# **  @param  $3  do not print any verbose output if "yes"
# **  @param  $4  file to redirect text output to
# **  @return n/a
# *******************************************************************

do_recursive_uninstallation()
{
    local info="${1}"
    local auto="${2}"
    local quiet="${3}"
    local animation="${4}"
    local outfile="${5}"

    # echo "Resolving package requirements..."
    ${EISMAN_BIN_PATH}/eisman_rtree.sh ${PACKAGELIST} \
        > "/tmp/tmpresult$$" &

    # show wait animation and fetch exit code
    if [ "${animation}" = "yes" ]
    then
        show_wait "searching..."
    fi
    wait $!

    if [ "$?" != 0 ]
    then
        echo 'error: uninstallation aborted!' >&2
        rm -f "/tmp/tmpresult$$"
        exit 1
    fi

    packages="$(cat /tmp/tmpresult$$)"
    rm -f "/tmp/tmpresult$$"

    if [ -z "${packages}" ]
    then
        echo "error: uninstallation aborted due to pending requirements!" >&2

        if [ "${quiet}" = "no" ]
        then
            mecho --info "List of pending requirements:"
            ${EISMAN_BIN_PATH}/eisman_usage.sh ${PACKAGELIST}
        fi
        exit 1
    fi

    # list packages found in query
    if [ "${quiet}" = "no" ]
    then
        if [ -n "${outfile}" ]
        then
            list_packages "${packages}" > "${outfile}"
        else
            list_packages "${packages}"
        fi
    fi

    if [ "${auto}" = "no"  -a "${info}" = "no" ]
    then
        res=$(/var/install/bin/ask "Continue" "yes")

        # if ask break, ask returned 255
        if [ $? = 255 ]
        then
            res="no"
        fi

        if [ "${res}" != "yes" ]
        then
            echo 'Uninstallation aborted by user!' >&2
            exit 1
        fi
    fi

    if [ "${info}" = "no" ]
    then
        # install packages listed in $packages
        uninstall_packages "${packages}"
    fi
}


# *******************************************************************
# **  main program
# *******************************************************************
main()
{
    local outfile=""
    local force='no'
    local update='no'
    local recursive='no'
    local arguments=''
    local animation="yes"
    local info='no'

    auto='no'
    quiet='no'

    while [ "${1:0:2}" = "--" ]
    do
        case ${1} in
        --help)
            show_help
            exit 0
            ;;
        --force)
            force='yes'
            arguments="${arguments} --force"
            shift
            ;;
        --auto)
            shift
            auto='yes'
            arguments="${arguments} --auto"
            ;;
        --quiet)
            shift
            quiet='yes'
            arguments="${arguments} --quiet"
            ;;
        --listonly|--info)
            shift
            info='yes'        # not a real uninstallation only show what would be done
            arguments="${arguments} --info"
            ;;
        --update)
            shift
            update='yes'
            arguments="${arguments} --update"
            ;;
        --recursive)
            shift
            recursive='yes'
            ;;
        --output)
            shift
            outfile="${1}"
            arguments="${arguments} --output=${outfile}"
            shift
            ;;
        --output=*)
            outfile="${1:9}"
            arguments="${arguments} --output=${outfile}"
            shift
            ;;
        --no-wait-anim)
            animation="no"
            shift
            ;;
        *)
            echo "error: unknown option \"${1}\"!" >&2
            echo
            show_help
            exit 1
            ;;
        esac
    done

    # read parameters
    while [ "$#" -ge 1 ]
    do
        PACKAGELIST="${PACKAGELIST} ${1}"
        shift
    done

    # exit upon empty package list
    if [ -z "${PACKAGELIST}" ]
    then
        echo "error: missing package parameter!" >&2
        echo
        show_help
        exit 1
    fi

    # echo "Resolving package requirements, if enabled ..."
    if [ "${recursive}" = "yes" ]
    then
        # recursive uninstallation
        do_recursive_uninstallation "${info}" "${auto}" "${quiet}" "${animation}" "${outfile}"
    else
        # normal uninstallation of one single package
        ${EISMAN_BIN_PATH}/eisman_uninstall.sh ${arguments} ${PACKAGELIST}
    fi
    exit $?
}

main "${@}"
