#!/bin/sh

xxx_build_package() {
    destdir=$1; shift
    name=$1; shift
    version=""

    [ $# -gt 0 ] && version="$1";
    #echo "v $version"
    if [ -n "$version" ]; then
        if echo "$version" | grep -E -qv -- '^-'; then
            shift
        else
            version="1-1"
        fi
    fi
    [ -n "$version" ] || version="1-1"

    params=""
    [ $# -gt 0 ] && params="$@";

    local log=$TMPDIR/$name.build.log

    eval ./build-test-rpm.sh -d $destdir -n $name -v $version $params >$log 2>&1
    [ $? -eq 0 ] || fail "build package '$name' failed with $(grep error $log | tr -d '\n')"

    if [ "$VERBOSE" = "vv" ]; then
        echo "./build-test-rpm.sh -d $destdir -n $name -v $version $params"
        cat $log
    fi

    BUILT_PACKAGE_NVR="$name-$version"
}

do_runpoldek() {
    typeset eec=$1; shift

    [ -z "$POLDEK_INSTALL" ] && fail 'empty $POLDEK_INSTALL'

    typeset cmd="$POLDEK_INSTALL $@"

    if is_verbose_mode; then
        msg "# executing $cmd"
        $cmd
    else
        $cmd >/dev/null 2>&1
    fi

    local ec=$?
    if [ "$eec" = "fail" ]; then
       [ $ec -eq 0 ] && fail "poldek succeed, but should fail"
    elif [ $ec -ne 0 ]; then
        fail "poldek failed with exit code $ec"
    fi

    return $?
}

runpoldek() {
    do_runpoldek "success" "$@"
}

runpoldek_failok() {
    do_runpoldek "fail" "$@"
}

# try to install package and check result
# usage: try_install <mode> <poldek switches> <package> <expected installed> [<expected removed>] [<extra_poldek_switches>]
do_try_install_package() {
    msg "do_try_install_package $# [$@]"
    typeset eec="$1"; shift
    typeset mode="$1"; shift

    typeset package=""
    typeset expected=""
    typeset rm_expected=""
    typeset poldek_opts=""
    while [ $# -gt 0 ]; do
        case "${1}" in
            -*)
                poldek_opts="$poldek_opts $1"
                shift
                ;;
            *)
                if [ -z "$package" ]; then
                    package="$1"
                elif [ -z "$expected" ]; then
                    expected="$1"
                elif [ -z "$rm_expected" ]; then
                    rm_expected="$1"
                else
                    echo "too much args?"
                    exit 1
                fi
                shift
                ;;
        esac
    done

    msg "do_try_install_package (eec=$eec, mode=$mode, opts=$poldek_opts): $package => [$expected] [$rm_expected]"

    [ "$expected" = "none" ] && expected=""
    typeset regexp=$(echo $expected | sed 's/,/|/g')
    typeset n_expected=$(echo $expected | sed 's|,|\n|g' | wc -l)
    if [ -n "$rm_expected" ]; then
        typeset rm_regexp=$(echo $rm_expected | sed 's/,/|/g')
        typeset rm_n_expected=$(echo $rm_expected | sed 's|,|\n|g' | wc -l)
    fi

    typeset cmd="$poldek_opts $package"
    if [ $# -gt 0 ]; then
        cmd="$1 $cmd"
        shift
    fi

    echo "$cmd" | grep -q -- '--test'
    local is_test=$?

    if is_verbose_mode; then
        GDB=${GDB:-""}
        if [ -n "$GDB" ]; then
            gdb --ex run --args $POLDEK_INSTALL $cmd --test
        fi
    fi

    if [ "$mode" = "rpm" ]; then
        do_runpoldek $eec $cmd
        return $?
    fi

    # dry run to check installation results
    typeset testop="--test"
    echo "$cmd" | grep -Pq '\-\-test'
    [ $? -eq 0 ] && testop=""

    typeset out=""
    if [ -n "$expected" -o -n "$rm_expected" ]; then
        out=$($POLDEK_INSTALL $cmd $testop --parsable-tr-summary | grep -E "^%[IDR]")
    fi

    do_runpoldek $eec $cmd

    if [ -n "$expected" ]; then
        typeset n_all=$(echo $out | sed 's|%|\n%|g' | grep -E '^%[ID]' | wc -l)
        typeset n=$(echo $out | sed 's|%|\n%|g' | grep -E "^%[ID] ($regexp)" | wc -l)
        assertEquals "unexpected ($n_all) number of packages (found $n)" "$n_all" "$n"
        assertEquals "not all or non expected packages installed (expected $n_expected: $expected, got $n)" "$n" "$n_expected"

        if [ "$n" != "$n_expected" -a is_verbose_mode ]; then
           msg "Installed:"
           echo $out | sed 's|%|\n%|g' | grep -E '^%[ID]' | nl

           msg "Installed requested ($regexp):"
           echo $out | sed 's|%|\n%|g' | grep -E "^%[ID] ($regexp)" | nl
        fi
    fi

    if [ -n "$rm_expected" ]; then
        typeset n_all=$(echo $out | sed 's|%|\n%|g' | grep -E '^%R' | wc -l)
        typeset n=$(echo  $out | sed 's|%|\n%|g' | grep -E "^%R ($rm_regexp)" | wc -l)
        assertEquals "unexpected ($n_all) number of packages removed (expected $n)" "$n_all" "$n"
        assertEquals "not all or non expected packages removed (expected $rm_expected)" "$n" "$rm_n_expected"
    fi
}

try_install_package_should_fail() {
    do_try_install_package "fail" "$@"
}

try_install_package() {
    do_try_install_package "success" "$@"
}

try_uninstall_package() {
    typeset mode="$1"; shift
    typeset poldek_opts="$1"; shift
    typeset package="$1"; shift
    typeset expected="$1"; shift
    [ $expected = "none" ] && expected=""

    typeset regexp=$(echo $expected | sed 's/,/|/g')
    typeset n_expected=$(echo $expected | sed 's|,|\n|g' | wc -l)

    typeset cmd="$poldek_opts $package"
    if [ $# -gt 0 ]; then
        cmd="$1 $cmd"
        shift
    fi

    # run to check exit code
    [ "$mode" != "rpm" ] && runpoldek $cmd

    # run again to check installation results
    if is_verbose_mode; then
        msg "# parsable"
        #gdb --ex run --args
        $POLDEK_UNINSTALL $cmd --test
    fi

    typeset out=$($POLDEK_UNINSTALL $cmd --parsable-tr-summary | grep -E "^%[DR]")
    [ $? -eq 0 ] || fail "$POLDEK_INSTALL $cmd failed"

    if [ -n "$expected" ]; then
        typeset n_all=$(echo $out | sed 's|%|\n%|g' | grep -E '^%[RD]' | wc -l)
        typeset n=$(echo $out | sed 's|%|\n%|g' | grep -E "^%[RD] ($regexp)" | wc -l)
        assertEquals "unexpected ($n_all) number of packages (expected $n)" "$n_all" "$n"
        assertEquals "not all or non expected packages uninstalled (expected $expected)" "$n" "$n_expected"
    fi
}
