#!/bin/sh

# This file is part of GNUnet.
# Copyright (C) 2018 Taler Systems SA
#
# Twister 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, or (at your option) any later version.
#
# Twister 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.
#
# You should have received a copy of the GNU General Public
# License along with Twister; see the file COPYING.  If not,
# write to the Free Software Foundation, Inc., 51 Franklin
# Street, Fifth Floor, Boston, MA 02110-1301, USA.

# @author Marcello Stanisci
# @author Christian Grothoff
#
# @file test_twister.sh
#
# @brief Twister testcases.


if ! which curl > /dev/null
then
    echo "curl not found";
    exit 77
fi

TWISTER_URL_V4="http://localhost:8888/"
TWISTER_URL="http://[::1]:8888/"

# Launch the Web server.
./test_twister_webserver &
web_server_pid=$!

echo "Webserver launched."

# Launch the Twister.
taler-twister-service -c ./test_twister.conf &
twister_service_pid=$!

echo "Twister launched."

sleep 1
if ! ps xo pid | grep -q ${twister_service_pid}; then
  echo Twister did not start correctly
  return 77
fi

# hack the response code.
taler-twister -c ./test_twister.conf --responsecode 202

status_code=$(curl -s ${TWISTER_URL} -o /dev/null \
  -w "%{http_code}")

# check status code was hacked
if ! test 202 = $status_code; then
  echo "Response code has not been hacked."
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi


echo "--responsecode 202 passed".

# malform response.
taler-twister -c ./test_twister.conf --malform
malformed_body=$(curl -s ${TWISTER_URL})

# check response body has been emptied
if test '{"hello":[{"this":"browser!"}],"when":"today"}' = \
    "$malformed_body"; then
  printf "Response body (%s) has not been emptied as expected\n" \
    "$malformed_body"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "--malform passed".

# flip string.
taler-twister -c ./test_twister.conf -f "when"
flip_body=$(curl -s ${TWISTER_URL})
flip_field=$(echo $flip_body | tr -d '"}{' | awk -F, '{print $2}' | awk -F: '{print $2}')

# check if pointed object was flipped.
if test "$flip_field" = 'today'; then
  printf "Response body (%s vs. %s) has not been flipped as expected\n" "$flip_body" "$flip_field"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "field-flip passed".

# delete object.
taler-twister -c ./test_twister.conf -d "hello.0"
emptied_body=$(curl -s ${TWISTER_URL})

# check if pointed object was deleted.
if ! test '{"hello":[],"when":"today"}' = "$emptied_body"; then
  printf "Response body (%s) has not been emptied as expected\n" \
    "$emptied_body"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "field-deletion passed".

# set boolean field
taler-twister -c ./test_twister.conf \
  -m "hello" \
  --value "true"
modobject_body=$(curl -s ${TWISTER_URL})

if ! test \
    '{"hello":true,"when":"today"}' = "$modobject_body"; then
  printf "Response body (%s) has not been modified as expected\n" \
    "$modobject_body"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "field-modification with boolean value passed".

# set field
taler-twister -c ./test_twister.conf \
  -m "hello" \
  --value "fake"
modobject_body=$(curl -s ${TWISTER_URL})

if ! test \
    '{"hello":"fake","when":"today"}' = "$modobject_body"; then
  printf "Response body (%s) has not been modified as expected\n" \
    "$modobject_body"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "field-modification with string passed".

# set header
taler-twister -c ./test_twister.conf \
  -H "Date" \
  --value "January 32nd"
modobject_body=$(curl -sI ${TWISTER_URL} | grep -Fi Date | tr -d '\r')
echo $modobject_body

if ! test \
    'Date: January 32nd' = "$modobject_body"; then
  printf "Response header (%s) has not been modified as expected\n" \
    "$modobject_body"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "download header-modification passed".

# check if cumulative mods work.
taler-twister -c ./test_twister.conf \
  -m "hello" -V "world" \
  --deleteobject "when"
cum_mods=$(curl -s ${TWISTER_URL})

if ! test '{"hello":"world"}' = $cum_mods; then
  printf "Response body (%s) has not been" \
         " cumulative-modified as expected\n" \
    "$cum_mods"
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

# check if Twister decompresses.
status_code=$(curl \
  -s "${TWISTER_URL}deflate-test" \
  -o /dev/null \
  -H "Content-Encoding: deflate" \
  -H "Content-Type: application/json" \
  --data-binary @body.json.deflate \
  -w "%{http_code}")

# check status code is okay.
if ! test 200 = $status_code; then
  echo "Compression failed (status == ${status_code})."
  kill $web_server_pid
  kill $twister_service_pid
  exit 1
fi

echo "cumulative mods passed".

# Just upload a big blob; first with PUT then with POST.
dd if=/dev/urandom of=BIGBLOB count=2 bs=1MB
printf "{\"things\": \"%s\"}" $(base64 BIGBLOB | tr -d '\n') > BIGBLOB.json

status_code=$(curl \
  -s "${TWISTER_URL}BIGPUT" \
  -o /dev/null \
  -X PUT \
  -H "Content-Type: application/json" \
  -d@BIGBLOB.json \
  -w "%{http_code}")

## check status code is okay.
if ! test 200 = $status_code; then
  echo "PUTting big blob failed (status == ${status_code})."
  kill $web_server_pid
  kill $twister_service_pid
  rm BIGBLOB*
  exit 1
fi
echo "PUT big load passed".

status_code=$(curl \
  -s "${TWISTER_URL}BIGPOST" \
  -o /dev/null \
  -X POST \
  -H "Content-Type: application/json" \
  -d@BIGBLOB.json \
  -w "%{http_code}")

## check status code is okay.
if ! test 200 = $status_code; then
  echo "POSTing big blob failed (status == ${status_code})."
  kill $web_server_pid
  kill $twister_service_pid
  rm BIGBLOB*
  exit 1
fi

echo "POST big load passed".

rm BIGBLOB*

# shutdown twister and webserver
kill $web_server_pid
kill $twister_service_pid

exit 0
