#!/bin/sh -e

TEMP=/tmp/gnubgtest.$$

if [ -n "$srcdir" ]; then
    dirparam="--datadir=$srcdir"
else
    dirparam=
fi

die () {
    echo "$1"
    exit 1
}

# Feature test
./gnubg -v > $TEMP || die '--- Feature test fails.'
grep -q Guile $TEMP && GUILE=yes || GUILE=""
grep -q databases $TEMP && DATABASES=yes || DATABASES=""
grep -q Window $TEMP && WINDOW=yes || WINDOW=""
rm -f $TEMP
echo '--- Feature test succeeds.'

# Test without -b; now requires bearoff database.
./gnubg $dirparam -t -r -n <> /dev/null || die \
    '--- Bearoff database test fails.'
echo '--- Bearoff database test succeeds.'

# Test without -n; now requires weights files.
./gnubg $dirparam -t -r <> /dev/null || die \
    '--- Neural net weights test fails.'
echo '--- Neural net weights test succeeds.'

# Make sure an opening 31 is played correctly.
./gnubg $dirparam -t -r << "EOF" | grep -q sGfwATDgc/ABMA || die \
    '--- Opening move test fails.'
set player both human
new game
set turn 0
set dice 3 1
set player 0 gnubg
play
EOF
echo '--- Opening move test succeeds.'

# Play a game with pubeval.
./gnubg $dirparam -t -r << "EOF" > /dev/null || die '--- Pubeval test fails.'
set automatic game no
set cube use no
set player both pubeval
new game
EOF
echo '--- Pubeval test succeeds.'

# Play a cubeless game.
./gnubg $dirparam -t -r << "EOF" > /dev/null || die '--- Self-play test fails.'
set automatic game no
set cube use no
set player both gnubg
new game
EOF
echo '--- Self-play test succeeds.'

# Play a cubeful game.
./gnubg $dirparam -t -r << "EOF" > /dev/null || die \
    '--- Cubeful self-play test fails.'
set automatic game no
set player both gnubg
new game
EOF
echo '--- Cubeful self-play test succeeds.'

# Test game navigation (and save game for later load test).
./gnubg $dirparam -t -r << EOF | grep -q '167.*163' || die \
    '--- Game navigation fails.'
set rng manual
set player both human
new game
31
8/5 6/5
roll
42
8/4 6/4
previous
previous
next
next
previous
save game $TEMP
show pipcount
EOF
echo '--- Game navigation succeeds.'

# Test resignation.
./gnubg $dirparam -t -r << "EOF" | grep -q 'a 0, b 4' || die \
    '--- Resignation test fails.'
set rng manual
set player both human
set player 0 name a
set player 1 name b
set automatic game no
new game
31
8/5 6/5
double
take
roll
42
8/4 6/4
resign gammon
accept
EOF
echo '--- Resignation test succeeds.'

# Test beavers.
./gnubg $dirparam -t -r << "EOF" | grep -q 'a 0, b 4' || die \
    '--- Beaver test fails.'
set rng manual
set player 0 human
set player 0 name a
set player 1 gnu
set player 1 name b
set automatic game no
new game
21
6/5 6/4
11
double
take
11
resign normal
EOF
echo '--- Beaver test succeeds.'

# Test saving.
./gnubg $dirparam -t -r << EOF | grep -q '163.*161' || die \
    '--- Load test fails.'
set player both human
load game $TEMP
show pipcount
EOF
rm -f $TEMP
echo '--- Load test succeeds.'

# Test miscellaneous commands.
./gnubg $dirparam -t -r << "EOF" > /dev/null || die \
    '--- Miscellaneous test fails.'
help
show player
new game
set evaluation plies 1
eval
set rollout trials 8
set rollout truncation 8
set rollout evaluation plies 0
set rollout varredn no
rollout
EOF
echo '--- Miscellaneous test succeeds.'

# Make sure the example game in the manual works.
./gnubg $dirparam -t -r << "EOF" | grep -q \
   'refuses the cube and gives up 1 point.' || die \
   '--- Manual example test fails.'
set seed 15
new game
8 5 6 5
roll
13 10 6 1
roll
13 11 6 1
double
EOF
echo '--- Manual example test succeeds.'

# Test Guile.
if [ "$GUILE" = "yes" ]; then
    ./gnubg $dirparam -t -r << "EOF" > /dev/null || die '--- Guile test fails.'
set rng manual
set player both human
set automatic game no
new game
31
8/5 6/5
:(define foo 123)
:
(catch #t (lambda ()
	    (or (= foo 123)
		(throw #t))
	    (or (equal? (board->position-id (current-board)) "sGfwATDgc/ABMA")
		(throw #t))
	    (or (< (vector-ref (evaluate-position (current-board)) 0) 0.5)
		(throw #t))
	    (primitive-exit 0))
       (lambda (tag . args)
	 (primitive-exit 1)))
EOF
    echo '--- Guile test succeeds.'
else
    echo '--- Guile test not available.'
fi
