#!/bin/bash
# This file is in the public domain.

set -eu

function clean_wallet() {
    rm -f "${WALLET_DB}"
    exit_cleanup
}


# Replace with 0 for nexus...
USE_FAKEBANK=1
if [ 1 = "$USE_FAKEBANK" ]
then
    ACCOUNT="exchange-account-2"
    BANK_FLAGS="-f -d x-taler-bank -u $ACCOUNT"
    BANK_URL="http://localhost:8082/"
else
    ACCOUNT="exchange-account-1"
    BANK_FLAGS="-ns -d iban -u $ACCOUNT"
    BANK_URL="http://localhost:18082/"
    echo -n "Testing for libeufin-bank"
    libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
    echo " FOUND"

fi

. setup.sh

echo -n "Testing for taler-harness"
taler-harness --help >/dev/null </dev/null || exit_skip " MISSING"
echo " FOUND"

# Launch exchange, merchant and bank.
setup -c "test_template.conf" \
      -r "merchant-exchange-default" \
      -em \
      $BANK_FLAGS
LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
CONF="test_template.conf.edited"
WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX)
EXCHANGE_URL="http://localhost:8081/"

# Install cleanup handler (except for kill -9)
trap clean_wallet EXIT

echo -n "First prepare wallet with coins ..."
rm -f "$WALLET_DB"
taler-wallet-cli \
    --no-throttle \
    --wallet-db="$WALLET_DB" \
    api \
    --expect-success 'withdrawTestBalance' \
  "$(jq -n '
    {
        amount: "TESTKUDOS:99",
        corebankApiBaseUrl: $BANK_URL,
        exchangeBaseUrl: $EXCHANGE_URL
    }' \
    --arg BANK_URL "${BANK_URL}" \
    --arg EXCHANGE_URL "$EXCHANGE_URL"
  )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out
echo -n "."
# FIXME-MS: add logic to have nexus check immediately here.
# sleep 10
echo -n "."
# NOTE: once libeufin can do long-polling, we should
# be able to reduce the delay here and run wirewatch
# always in the background via setup
taler-exchange-wirewatch \
    -a "$ACCOUNT" \
    -L "INFO" \
    -c "$CONF" \
    -t &> taler-exchange-wirewatch.out
echo -n "."
timeout 60 taler-wallet-cli \
    --wallet-db="$WALLET_DB" \
    run-until-done \
    2>wallet-withdraw-finish-1.err \
    >wallet-withdraw-finish-1.out
echo " OK"

CURRENCY_COUNT=$(taler-wallet-cli --wallet-db="$WALLET_DB" balance | jq '.balances|length')
if [ "$CURRENCY_COUNT" = "0" ]
then
    exit_fail "Expected least one currency, withdrawal failed. check log."
fi

#
# CREATE INSTANCE FOR TESTING
#


echo -n "Configuring merchant instance ..."

STATUS=$(curl -H "Content-Type: application/json" -X POST \
    -H 'Authorization: Bearer secret-token:super_secret' \
    http://localhost:9966/management/instances \
    -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \
    -w "%{http_code}" -s -o /dev/null)

if [ "$STATUS" != "204" ]
then
    exit_fail "Expected '204 No content' response. Got instead $STATUS"
fi
echo "Ok"

echo -n "Configuring merchant account ..."

if [ 1 = "$USE_FAKEBANK" ]
then
    FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree"
else
    FORTYTHREE=$(get_payto_uri fortythree x)
fi

# add bank account
STATUS=$(curl -H "Content-Type: application/json" -X POST \
    -H 'Authorization: Bearer secret-token:super_secret' \
    http://localhost:9966/private/accounts \
    -d '{"payto_uri":"'"$FORTYTHREE"'"}' \
    -w "%{http_code}" -s -o /dev/null)

if [ "$STATUS" != "200" ]
then
    exit_fail "Expected '200 OK' response. Got instead $STATUS"
fi
echo "OK"

echo -n "Adding same account again ..."
# add same bank account again (check idempotency)
STATUS=$(curl -H "Content-Type: application/json" -X POST \
    -H 'Authorization: Bearer secret-token:super_secret' \
    http://localhost:9966/private/accounts \
    -d '{"payto_uri":"'"$FORTYTHREE"'"}' \
    -w "%{http_code}" -s -o /dev/null)

if [ "$STATUS" != "200" ]
then
    exit_fail "Expected '200 OK' response. Got instead $STATUS"
fi
echo "OK"

echo -n "Checking idempotency ..."
curl -H "Content-Type: application/json" \
     -H 'Authorization: Bearer secret-token:super_secret' \
     http://localhost:9966/private/accounts > "$LAST_RESPONSE" 2> /dev/null
NUM=$(jq '.accounts|length' < "$LAST_RESPONSE")

if [ "$NUM" != "1" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 1 account. got: $NUM"
fi
echo " OK"


echo -n "Creating order with non-existing POT..."
STATUS=$(curl 'http://localhost:9966/private/orders' \
    -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","order_default_money_pot":1}}' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "404" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 404, money pot unknown. got: $STATUS"
fi
echo "OK"


echo -n "Creating money pot..."
STATUS=$(curl 'http://localhost:9966/private/pots' \
    -d '{"description":"First pot","pot_name":"#1"}' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "200" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 200, pot created. got: $STATUS"
fi
MONEY_POT=$(jq -r .pot_serial_id < "$LAST_RESPONSE")
echo "OK"


echo -n "Creating order with money pot..."
STATUS=$(curl 'http://localhost:9966/private/orders' \
    -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","order_default_money_pot":'"$MONEY_POT"'}}' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "200" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 200, order created. got: $STATUS"
fi

ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")

echo "OK"

echo -n "Checking created order without TOKEN..."
STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID" \
              -w "%{http_code}" -s -o "$LAST_RESPONSE")
PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE")
if [ "$PAY_URI" == "null" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected non-NULL payuri. got $PAY_URI"
fi
echo "OK"

NOW=$(date +%s)

echo -n "Pay first order ${PAY_URI} ..."
taler-wallet-cli \
    --no-throttle \
    --wallet-db="$WALLET_DB" \
    handle-uri "${PAY_URI}" \
    -y 2> wallet-pay1.err > wallet-pay1.log
timeout 60 taler-wallet-cli \
    --no-throttle \
    --wallet-db="$WALLET_DB" \
    run-until-done \
    2> wallet-finish-pay1.err \
    > wallet-finish-pay1.log
NOW2=$(date +%s)
echo " OK (took $(( NOW2 - NOW )) secs )"


echo -n "Checking money pot..."
STATUS=$(curl 'http://localhost:9966/private/pots' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "200" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 200, pot status. got: $STATUS"
fi
MONEY_POT_BALANCE=$(jq -r .pots[0].pot_totals[0] < "$LAST_RESPONSE")

if [ "$MONEY_POT_BALANCE" != "TESTKUDOS:7" ]
then
    exit_fail "Expected 'TESTKUDOS:7' balance. Got instead $MONEY_POT_BALANCE"
fi

echo "OK"

echo -n "Patching money pot ..."
STATUS=$(curl "http://localhost:9966/private/pots/$MONEY_POT" -X PATCH \
    -d  '{"description":"Updated pot","expected_pot_totals":[],"new_pot_totals":["KUDOS:23"],"pot_name":"#1p"}' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "204" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 204, pot updated. got: $STATUS"
fi
echo "OK"

echo -n "Schedule periodic report..."
STATUS=$(curl 'http://localhost:9966/private/reports' \
    -d '{"description":"My report","program_section":"file","mime_type":"application/pdf","data_source":"/private/statistics-report/transactions","target_address":"'"${TMPDIR:-/tmp}/last-report"'","report_frequency":{"d_us" : 50000000}}' \
    -w "%{http_code}" -s -o "$LAST_RESPONSE")

if [ "$STATUS" != "200" ]
then
    cat "$LAST_RESPONSE" >&2
    exit_fail "Expected 200, pot created. got: $STATUS"
fi
REPORT_SERIAL_ID=$(jq -r .report_serial_id < "$LAST_RESPONSE")
echo "OK"

echo -n "Generate periodic report..."
taler-merchant-report-generator \
    -c "$CONF" \
    --test \
    --timetravel=100000000 \
    --log=INFO 2> report-generator.log
echo " OK"



exit 0
