#!/usr/bin/env bash
. wvtest.sh
. wvtest-bup.sh
. dev/lib.sh

set -o pipefail

top="$(WVPASS pwd)" || exit $?
tmpdir="$(WVPASS wvmktempdir)" || exit $?
export BUP_DIR="$tmpdir/bup"

bup() { "$top/bup" "$@"; }

WVPASS cd "$tmpdir"

# necessary for 0 == 1970-01-01 00:00
export TZ=UTC

WVSTART "init"
WVPASS bup init

mkdir "$tmpdir/save"
for f in $(seq 9) ; do
    touch -t 200${f}01010000 "$tmpdir/save/$f"
done
mkdir "$tmpdir/save/a"
touch -t 199901010000 "$tmpdir/save/a/1"

WVSTART "metadata read error for a file"
WVPASS bup index "$tmpdir/save"

# now do a hack to inject save errors while reading metadata
# essentially, we create a bup-save command for ourselves
# that gets an error for the .../5 file in metadata.from_path()
cat > "$tmpdir/bup-save" << EOF
#!/usr/bin/env $top/dev/bup-python
from bup import metadata

orig_from_path = metadata.from_path
def from_path(path, *args, **kw):
    if path.endswith(b'/5'):
        raise IOError('intentionally failing metadata read for .../5')
    return orig_from_path(path, *args, **kw)
metadata.from_path = from_path

exec(open("$top/lib/cmd/bup-save", "rb").read())
EOF
chmod +x "$tmpdir/bup-save"

# use it to save the data
"$tmpdir/bup-save" -n test "$tmpdir/save"

# this should work anyway
WVPASS bup ls -l "test/latest/$tmpdir/save"
# also check the *right* data was returned
lsout="$(bup ls -l "test/latest/$tmpdir/save")"
for f in 1 2 3 4   6 7 8 9 ; do
    if ! echo "$lsout" | grep "200${f}-01-01 00:00 $f" ; then
        WVFAIL echo incorrect date for $f
    fi
done
# and ensure we actually failed, and the above script/hack didn't break
if ! echo "$lsout" | grep "1970-01-01 00:00 5" ; then
    WVFAIL echo unexpected date for file 5
fi


WVSTART "metadata read error for a folder"
WVPASS bup index --clear
WVPASS bup index "$tmpdir/save"

cat > "$tmpdir/bup-save" << EOF
#!/usr/bin/env $top/dev/bup-python
from bup import metadata

orig_from_path = metadata.from_path
def from_path(path, *args, **kw):
    if path.endswith(b'/a'):
        raise IOError('intentionally failing metadata read for .../a')
    return orig_from_path(path, *args, **kw)
metadata.from_path = from_path

exec(open("$top/lib/cmd/bup-save", "rb").read())
EOF
chmod +x "$tmpdir/bup-save"

# use it to save the data
"$tmpdir/bup-save" -n test "$tmpdir/save"

# this should work anyway
WVPASS bup ls -l "test/latest/$tmpdir/save"
if ! bup ls -l "test/latest/$tmpdir/save/a" | grep '1999-01-01 00:00 1' ; then
    WVFAIL unexpected date for file a/1
fi
# and ensure we actually failed, and the above script/hack didn't break
if ! bup ls -l "test/latest/$tmpdir/save" | grep "1970-01-01 00:00 a" ; then
    WVFAIL unexpected date for directory a
fi


WVSTART "duplicate entries"
WVPASS bup index --clear
WVPASS bup index "$tmpdir/save"

cat > "$tmpdir/bup-save" << EOF
#!/usr/bin/env $top/dev/bup-python
from bup import index

Reader = index.Reader
class DupReader(index.Reader):
    def filter(self, *args, **kw):
        for transname, ent in Reader.filter(self, *args, **kw):
            # duplicate a file and a folder
            if ent.name.endswith(b'/5') or ent.name.endswith(b'/a/'):
                yield transname, ent
            yield transname, ent
index.Reader = DupReader

exec(open("$top/lib/cmd/bup-save", "rb").read())
EOF
chmod +x "$tmpdir/bup-save"

# use it to save the data
"$tmpdir/bup-save" -n test "$tmpdir/save"

# this should work
WVPASS bup ls -l "test/latest/$tmpdir/save"

# check that there are no duplicates
lsout=$(bup ls -l "test/latest/$tmpdir/save")
WVPASSEQ "$(echo "$lsout" | sort | uniq -d)" ""

# and we should get the *right* data for each entry
for f in $(seq 9) ; do
    if ! echo "$lsout" | grep "200${f}-01-01 00:00 $f" ; then
        WVFAIL echo incorrect metadata for $f
    fi
done


WVPASS rm -rf "$tmpdir"
