#! /bin/sh

ZEROS=0000000000000000000000000000000000000000

D=$(cd $(dirname "$0") && pwd)
cd "$D" || exit 1
. ./helper-functions.sh || exit 1
MULTIMAIL="$D/../git-multimail/git_multimail.py"
POST_RECEIVE="$D/../git-multimail/post-receive.example"

TESTREPO=$("$D/create-test-repo")

HOME="$D"
XDG_CONFIG_HOME="$D"
GIT_CONFIG_NOSYSTEM=1
export HOME XDG_CONFIG_HOME GIT_CONFIG_NOSYSTEM

cd "$TESTREPO"

test_email() {
    REFNAME="$1"
    OLDREV="$2"
    NEWREV="$3"
    pecho "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$MULTIMAIL"
}

test_create() {
    REFNAME="$1"
    NEWREV=$(git rev-parse "$REFNAME")
    test_email "$REFNAME" "$ZEROS" "$NEWREV"
}

test_update() {
    REFNAME="$1"
    OLDREV=$(git rev-parse "$2")
    NEWREV=$(git rev-parse "$REFNAME")
    test_email "$REFNAME" "$OLDREV" "$NEWREV"
}

test_delete() {
    REFNAME="$1"
    OLDREV=$(git rev-parse "$REFNAME")
    git update-ref -d "$REFNAME" "$OLDREV" &&
    test_email "$REFNAME" "$OLDREV" "$ZEROS"
    RETCODE=$?
    git update-ref "$REFNAME" "$OLDREV" ||
        error "Error replacing reference $REFNAME to $OLDREV"
    return $RETCODE
}

test_rewind() {
    REFNAME="$1"
    OLDREV=$(git rev-parse "$REFNAME")
    NEWREV=$(git rev-parse "$2")
    git update-ref "$REFNAME" "$NEWREV" "$OLDREV" &&
    test_email "$REFNAME" "$OLDREV" "$NEWREV"
    RETCODE=$?
    git update-ref "$REFNAME" "$OLDREV" ||
        error "Error replacing reference $REFNAME to $OLDREV"
    return $RETCODE
}

# Like test_update, but using example post-receive script:
test_hook() {
    REFNAME="$1"
    OLDREV=$(git rev-parse "$2")
    NEWREV=$(git rev-parse "$REFNAME")
    pecho "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$POST_RECEIVE"
}

test_create refs/heads/master
git config multimailhook.refChangeShowGraph true
git config multimailhook.graphOpts '--oneline'
test_update refs/heads/master refs/heads/master^^
git config multimailhook.refChangeShowGraph false
git config --unset multimailhook.graphOpts
test_update refs/heads/master refs/heads/feature
test_delete refs/heads/master
test_rewind refs/heads/master refs/heads/master^^
test_rewind refs/heads/master refs/heads/feature
test_rewind refs/heads/master refs/heads/master^

test_update refs/heads/release refs/heads/release^^^^

# Should send both summary and revision email:
test_update refs/heads/release refs/heads/release^
# Should send a combined email:
git config multimailhook.refchangelist 'Commit List <commitlist@example.com>'
test_update refs/heads/release refs/heads/release^
git config multimailhook.refchangelist 'Refchange List <refchangelist@example.com>'

git config multimailhook.refChangeShowGraph true
test_rewind refs/heads/release refs/heads/release^^
git config multimailhook.refChangeShowGraph false

test_create refs/heads/feature
test_update refs/heads/feature refs/heads/feature^^^
test_rewind refs/heads/feature refs/heads/feature^^^
test_delete refs/heads/feature

test_create refs/tags/tag
test_update refs/tags/tag refs/heads/master
test_delete refs/tags/tag

test_create refs/tags/tag-annotated
test_update refs/tags/tag-annotated refs/heads/master
test_delete refs/tags/tag-annotated

test_create refs/tags/tag-annotated-new-content
test_update refs/tags/tag-annotated-new-content refs/heads/master
test_delete refs/tags/tag-annotated-new-content

test_create refs/tags/tree-tag
test_update refs/tags/tree-tag refs/heads/master
test_delete refs/tags/tree-tag

test_create refs/tags/recursive-tag
test_update refs/tags/recursive-tag refs/heads/master
test_delete refs/tags/recursive-tag

test_create refs/remotes/remote
test_update refs/remotes/remote refs/heads/master
test_delete refs/remotes/remote

test_create refs/foo/bar
test_update refs/foo/bar refs/heads/master
test_delete refs/foo/bar

test_hook refs/heads/master refs/heads/master^^

git config multimailhook.scanCommitForCc true
test_update refs/heads/formatting refs/heads/formatting^^^

git config multimailhook.refChangeShowGraph true
f=$(git rev-parse feature)
git branch -D feature
# git log --decorate behaves differently with different Git versions
# on non-detached HEAD
git update-ref --no-deref HEAD HEAD
git config multimailhook.commitList ''
test_update refs/heads/master refs/heads/foo
git config multimailhook.refChangeShowGraph false
git branch feature "$f"

for o in mailinglist refchangelist announcelist commitlist; do
    git config multimailhook."$o" ''
done
test_update refs/heads/formatting refs/heads/formatting^^^

rm -rf "$TESTREPO"

