#!/bin/sh

tearDown() {
    POLDEK_TESTING_DENIED_FILES=""
    [ -n "$REPO" ] && rm -rf $REPO/packages.*
    [ -n "$TMPDIR" ] && rm -rf $TMPDIR/*.*
}

setUp() {
    tearDown
}

abort() {
    echo "$1, ABORT"
    exit 1
}

build_repo_packages() {
    local n=$(find $SOURCE_REPO/ -name \*.rpm | wc -l)
    if [ $n -lt 20 ]; then
        for i in a b c d e f g h i j k l m n o p r s t u w x y v z; do
            rpm="$i-1-1.noarch.rpm"
            [ -f "$SOURCE_REPO/$rpm" ] && continue
            ./build-test-rpm.sh -d $SOURCE_REPO/ -n $i -v 1  >/dev/null 2>&1 || abort "build package $i failed"
            ./build-test-rpm.sh -d $SOURCE_REPO/ -n "$i$i" -v 1  >/dev/null 2>&1 || abort "build package $i$i failed"
            ./build-test-rpm.sh -d $SOURCE_REPO/ -n "$i$i$i" -v 1  >/dev/null 2>&1 || abort "build package $i$i$i failed"
        done
    fi
}

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
    if [ $? -ne 0 ]; then
        fail "build package '$name' failed"
        exit
    fi

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

    BUILT_PACKAGE_NVR="$name-$version"
}

oneTimeSetUp() {
    [ ! -d "$PWD/sh/lib" ] && abort "$PWD is not a tests directory (missing sh/lib)"

    SHLIBDIR="$PWD/sh/lib"

    SOURCE_REPO=${SOURCE_REPO:-"${PWD}/repo"}
    mkdir -p $SOURCE_REPO
    [ ! -d "$SOURCE_REPO" ] && abort "$SOURCE_REPO: no such directory"

    TMP=${TMP:-""}
    TMPDIR=${TMPDIR:-""}
    [ -z "$TMP" ] && TMP="${TMPDIR}"
    [ -z "$TMP" ] && TMP="/tmp"
    TMP="${TMP}/poldek-tests"
    TMPDIR="$TMP"

    export TMP TMPDIR

    rm -rf $TMPDIR
    mkdir -p $TMPDIR
    [ ! -d $TMPDIR ] && abort "$TMPDIR: no such directory"


    CACHEDIR="$TMPDIR/kesz"
    rm -rf $CACHEDIR
    mkdir -p $CACHEDIR
    [ ! -d $CACHEDIR ] && abort "$CACHEDIR: no such directory"

    REPO="$TMPDIR/repo"
    REPOURL="test://$TMPDIR/repo/"
    REPONAME="testrepo"

    mkdir -p $REPO
    [ ! -d $REPO ] && abort "mkdir $REPO failed?"

    PATH="$PATH:$PWD/sh/lib/"

    POLDEK="$PWD/../cli/poldek $QUIET"
    $POLDEK --version >/dev/null; # produce .libs/lt-poldek
    POLDEK="$PWD/../cli/.libs/lt-poldek $QUIET"
    POLDEK_NOCONF="$POLDEK --noconf -Ovfile_retries=1 --cachedir $CACHEDIR"
    POLDEK_UP="$POLDEK --conf ./sh/lib/vftest-fetch.conf --cachedir $CACHEDIR"

    POLDEK_RAW="$PWD/../cli/.libs/lt-poldek"
    POLDEK_RAW_UP="$POLDEK --conf ./sh/lib/vftest-fetch.conf --cachedir $CACHEDIR"

    build_repo_packages
    ln -sf $SOURCE_REPO/*.rpm $REPO/ || abort "make symlinks failed"
    tearDown
}

poldek_up() {
    $POLDEK_UP -Osource="$REPONAME,type=pndir $REPOURL" $@
}

poldek_quiet_up() {
    local cmd=$(echo $POLDEK_UP | sed 's|\-v|-q|g');
    $cmd -Osource="$REPONAME,type=pndir $REPOURL" $@
}

oneTimeTearDown() {
   if echo $TMPDIR | grep -q poldekTest; then rm -rf $TMPDIR; fi
   tmpdir=$(dirname $TMPDIR)
   TMP="$tmpdir"
   TMPDIR="$tmpdir"
}

die_if_empty_index() {
    die_if_invalid_index $1 ""
}

die_if_invalid_index() {
    anindex=$1
    expected_packages=$2

    GREP="zgrep"
    CAT="zcat"
    if echo $anindex | grep -qP '.(ndir|toc)$'; then
        GREP="grep"
        CAT="cat"
    elif echo $anindex | grep -qP '.gz$'; then
        GREP="zgrep"
        CAT="zcat"
    elif echo $anindex | grep -qP '.zst$'; then
        GREP="zstdgrep"
        CAT="zstdcat"
    fi

    if [ ! -f $anindex ]; then
        fail "$anindex not created"
        return
    fi

    if echo $anindex | grep -q "diff.toc"; then
        expected_lines="$expected_packages"

        lines=$($CAT $anindex | wc -l)
        if [ "$lines" != "$expected_lines" ]; then
            fail "$anindex contains $lines lines, expected $expected_lines"
        fi
        return
    fi

    anindex_type="pdir"
    if echo $anindex | grep -q \.ndir\.; then anindex_type="pndir"; fi
    if echo $anindex | grep -qP \.ndir$; then anindex_type="pndir"; fi
    anindex_real_type="pdir"

    if $GREP -q '^tndb[0-9]\.[0-9]' $anindex; then
        anindex_real_type="pndir"
    fi

    if [ "$anindex_real_type" != "$anindex_type" ]; then
        fail "invalid $anindex type $anindex_type, real is $anindex_real_type"
    fi

    if $GREP -q 'Contains 0 packages' $anindex; then
        if [ "$expected_packages" != "0" ]; then
            fail "empty $anindex"
        fi
    fi

    if [ -n "$expected_packages" ]; then
       if ! $GREP -q "Contains $expected_packages packages" $anindex; then
            fail "$anindex: number of packages mismatch"
       fi
    fi
}


add_package_to_repo() {
    for p in $(ls $SOURCE_REPO/*.rpm); do
        [ ! -f $p ] && fail "no packages in $SOURCE_REPO?"
        [ ! -f $p ] && break
        package=$(basename $p)

        if [ ! -f "$REPO/$package" ]; then
            ln -sf $p $REPO/$package
            msg "added $package"
            return 0
        fi
    done
}


remove_package_from_repo() {
    package=$(find $REPO -name \*.rpm | head -1)
    rm -f $package
    msg "removed $(basename $package)"
}

random_package() {
    perl -e '@s=(a..z); print $s[rand(@s)]'
}

random_change_repo() {
    to_add=$(random_package)
    to_del=$(random_package)

    while [ -f $REPO/$to_add-*.rpm ]; do
        to_add=$(random_package)
    done

    if [ ! -f $REPO/$to_del-*.rpm ]; then
        to_del=$(random_package)
    fi

    [ "$to_add" == "$to_del" ] && to_del="none"
    msg "adding $to_add, removing $to_del";

    nadded=0
    nremoved=0
    for i in $SOURCE_REPO/${to_add}*.rpm; do
        bn=$(basename $i);

        [ ! -f $i ] && continue;
        [ -f $REPO/$bn ] && continue;

        nadded=$(expr $nadded + 1)
        msg "    - add $bn"
        ln -sf $i $REPO/$bn
    done

    for i in $REPO/${to_del}*.rpm; do
        bn=$(basename $i);

        [ ! -f $i ] && continue
        msg "   - rm $bn"
        rm -f $i
        nremoved=$(expr $nremoved + 1)
    done
    nchanges=$(expr $nadded + $nremoved)
    [ "$nchanges" = "0" ] && random_change_repo

    # avoid empty repo
    n=$(ls $REPO/*.rpm | wc -l)
    [ "$n" = "0" ] && random_change_repo

    #msg "Added $nadded and $nremoved removed"
}
