#!/bin/bash

# Copyright (C) 2018, Xavier <yadd@debian.org>
#               2019-2020, Andrius Merkys <merkys@debian.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 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# On Debian systems, the complete text of the GNU General Public License
# version 3 can be found in the /usr/share/common-licenses/GPL-3 file.

set -u
#set -x

DEB_HOST_OS="$(dpkg-architecture -qDEB_HOST_ARCH_OS)"
if [ "$DEB_HOST_OS" = "kfreebsd" ]; then
    # kbsd has a non-working semaphore, that is needed here.
    echo "This test is not supported on $(dpkg-architecture -qDEB_HOST_ARCH), skipping"
    exit 0
fi
DEB_HOST_ARCH="$(dpkg-architecture -qDEB_HOST_ARCH)"
if [ "$DEB_HOST_ARCH" = "i386" ]; then
    echo "To \"help\" Ubuntu that has a fundamentally broken i386 (so that we can't depend on svn), this test is simply skipped on i386."
    exit 0
fi

TESTTYPE=Svn
. ./lib_test_uscan

COMMAND="chronic_sh uscan --no-conf --compression=xz --dehs"

# prevent the local from messing with this test
export HOME=""
export XDG_CONFIG_HOME=""

# comment out for debug
#COMMAND="$COMMAND --verbose"
#COMMAND="$COMMAND --debug"

cleanup(){
    rm -rf "$TEMP_PKG_DIR"
}

spawnSvnRepo(){
    mkdir -p "$TEMP_PKG_DIR/repo"
    (cd "$TEMP_PKG_DIR/repo" || exit 1
    chronic_sh svnadmin create .)
    mkdir -p "$TEMP_PKG_DIR/working-copy"
    (cd "$TEMP_PKG_DIR/working-copy" || exit 1
    chronic_sh svn checkout "file:///$TEMP_PKG_DIR/repo" .
    chronic_sh mkdir trunk tags
    touch trunk/changelog trunk/file.c
    chronic_sh svn add trunk tags
    chronic_sh svn commit -m 'Init'
    export TZ=UTC
    for version in 1.0 2.0; do
        echo "# Version $version" >> trunk/file.c
        cat >> trunk/changelog <<END
Version $version

END
        chronic_sh faketime -f '2000-01-01 12:34:56' svn commit -m "Releasing $version"
        chronic_sh faketime -f '2000-01-01 12:34:56' svn copy ^/trunk "^/tags/v$version" -m "Version $version"
    done)
}

trap cleanup EXIT

# shellcheck source=shunit2-helper-functions.sh
. "${0%/*}/shunit2-helper-functions.sh"

PKG=foo

makeDebianDir() {
    WATCHARGS=$1
    TEMP_PKG_DIR=$(mktemp -d --tmpdir="$SHUNIT_TMPDIR" uscan_svn.XXXXXX)
    if [ -z "$TEMP_PKG_DIR" ]; then
        echo "Failed to create temporary directory" >&2
        exit 1
    fi
    mkdir -p "$TEMP_PKG_DIR/$PKG/debian/source"
    spawnSvnRepo

    cat <<END > "$TEMP_PKG_DIR/$PKG/debian/watch"
version=4
opts="mode=svn,$WATCHARGS" \
file:///$TEMP_PKG_DIR/repo/tags v([\\d\\.]+)\/ debian
END

    cat <<END > "$TEMP_PKG_DIR/$PKG/debian/changelog"
$PKG (0-1) unstable; urgency=low

  * Initial release

 -- Joe Developer <jd@debian.org>  Mon, 02 Nov 2013 22:21:31 -0100
END
    echo '3.0 (quilt)' > "$TEMP_PKG_DIR/$PKG/debian/source/format"
}

makeDebianDirHead() {
    WATCHARGS=$1
    makeDebianDir "$WATCHARGS"
    cat <<END > "$TEMP_PKG_DIR/$PKG/debian/watch"
version=4
opts="mode=svn,$WATCHARGS" \
file:///$TEMP_PKG_DIR/repo/trunk HEAD
END
}

helperLaunch() {
    WATCHARGS=$1
    ARG="${2:-}"
    if test "$ARG" = "HEAD"; then
        makeDebianDirHead "$WATCHARGS"
    else
        makeDebianDir "$WATCHARGS"
    fi
    ( cd "$TEMP_PKG_DIR/$PKG" || exit 1 ; $COMMAND --watchfile=debian/watch )
    assertEquals "uscan: exit_code!=0 but exit_code=0" "0" "$?"
}

helperLaunchFail() {
    WATCHARGS=$1
    ARG="${2:-}"
    if test "$ARG" = "HEAD"; then
        makeDebianDirHead "$WATCHARGS"
    else
        makeDebianDir "$WATCHARGS"
    fi
    # discard output as it's expected to fail
    ( cd "$TEMP_PKG_DIR/$PKG" || exit 1 ; $COMMAND --watchfile=debian/watch > /dev/null)
    assertEquals "uscan: exit_code!=2 but exit_code=2" "2" "$?"
}

testSvn() {
    helperLaunch "pgpmode=none"
    TARBALL="${PKG}_2.0.orig.tar.xz"
    CHECKSUM=$(xz --decompress --stdout "$TEMP_PKG_DIR/${PKG}-2.0.tar.xz" | sha1sum | awk '{print $1}')
    assertTrue 'downloaded tarfile not present' "[ -f '$TEMP_PKG_DIR/${PKG}-2.0.tar.xz' ]"
    assertTrue 'pristine tarball is not created' "[ -f '$TEMP_PKG_DIR/$TARBALL' ]"
    assertTrue 'pristine tarball is not a symlink' "[ -L '$TEMP_PKG_DIR/$TARBALL' ]"
    if [ "$CHECKSUM" != 'c362837a450fd9d5a8649aa3a23ad863af14bc17' ]; then
        set -x
        echo "Copying the faulty tarball to the artefact directory, if available..."
        if [ -n "${AUTOPKGTEST_ARTIFACTS:-}" ] && [ -d "$AUTOPKGTEST_ARTIFACTS" ]; then
            cp -v "$TEMP_PKG_DIR/${PKG}-2.0.tar.xz" "$AUTOPKGTEST_ARTIFACTS"/
        fi
        set +x
    fi
    assertTrue 'checksums do not match' "[ '${CHECKSUM}' = 'c362837a450fd9d5a8649aa3a23ad863af14bc17' ]"
    cleanup
}

testSvnPgpmodeDefault() {
    helperLaunch "pgpmode=default"
    TARBALL="${PKG}_2.0.orig.tar.xz"
    assertTrue 'downloaded tarfile not present' "[ -f '$TEMP_PKG_DIR/${PKG}-2.0.tar.xz' ]"
    assertTrue 'pristine tarball is not created' "[ -f '$TEMP_PKG_DIR/$TARBALL' ]"
    assertTrue 'pristine tarball is not a symlink' "[ -L '$TEMP_PKG_DIR/$TARBALL' ]"
    cleanup
}

testSvnPgpmodeNext() {
    helperLaunchFail "pgpmode=next"
    cleanup
}

testSvnHead() {
    helperLaunch "pgpmode=none" HEAD
    ORIG="$TEMP_PKG_DIR/foo_0.0~svn4.orig.tar.xz"
    UPSTREAM="$TEMP_PKG_DIR/foo-0.0~svn4.tar.xz"
    assertTrue 'downloaded tarfile not present' "[ -f '$UPSTREAM' ]"
    assertTrue 'pristine tarball is not created' "[ -f '$ORIG' ]"
    assertTrue 'pristine tarball is not a symlink' "[ -L '$ORIG' ]"
    cleanup
}

testSvnHeadMangle() {
    helperLaunch "pgpmode=none,filenamemangle=s/^@PACKAGE@-[^~]+/@PACKAGE@-1.23.45/" HEAD
    ORIG="$TEMP_PKG_DIR/foo_1.23.45~svn4.orig.tar.xz"
    UPSTREAM="$TEMP_PKG_DIR/foo-1.23.45~svn4.tar.xz"
    assertTrue 'downloaded tarfile not present' "[ -f '$UPSTREAM' ]"
    assertTrue 'pristine tarball is not created' "[ -f '$ORIG' ]"
    assertTrue 'pristine tarball is not a symlink' "[ -L '$ORIG' ]"
    cleanup
}

# shellcheck disable=SC1091
. shunit2
