#!/bin/bash

# Copyright 2018 Stellar Development Foundation and contributors. Licensed
# under the Apache License, Version 2.0. See the COPYING file at the root
# of this distribution or at http://www.apache.org/licenses/LICENSE-2.0

BASE_INSTANCE="$1"
TESTS="$2"
if [[ -z "$TEMP_POSTGRES" ]]; then
    TEMP_POSTGRES=1
fi

STELLAR_CORE_DEFAULT_TEST_PARAMS="--ll fatal -w NoTests -a -r simple"
if [[ "$ALL_VERSIONS" != "" ]]; then
    STELLAR_CORE_DEFAULT_TEST_PARAMS="$STELLAR_CORE_DEFAULT_TEST_PARAMS --all-versions"
fi
if [[ "$INTERACTIVE" == "0" ]]; then
    STELLAR_CORE_DEFAULT_TEST_PARAMS="$STELLAR_CORE_DEFAULT_TEST_PARAMS --disable-dots"
fi

: ${STELLAR_CORE_TEST_PARAMS=$STELLAR_CORE_DEFAULT_TEST_PARAMS}

PGDIRS=$(exec 2>/dev/null; cd /usr/lib/postgresql && ls -1d */bin | sort -rn | xargs realpath)

findpg() {
    local cmd="$1"
    command -v "$cmd" > /dev/null && return
    for dir in /usr/bin /usr/local/bin $PGDIRS; do
        if [[ -x "$dir/$cmd" ]]; then
           PATH="${PATH}:$dir"
           return
        fi
    done
}

findpg psql
PSQL=psql

findpg pg_ctl
PGCTL=pg_ctl

if [ "$(which $PGCTL)" == "" ]; then
    findpg pg_ctlcluster
    PGCTL=pg_ctlcluster

    if [ "$(which $PGCTL)" == "" ]; then
        echo "Could not find pg_ctl or pg_ctlcluster"
        exit 1
    fi
fi

cleanup() {
    $PGCTL stop -D $PGDATA -m immediate
    rm -rf "$PGDATA"
    exit
}

# Creates a temporary postgres database cluster, runs a command (or a
# shell), then deletes the database cluster.  If PGDATA is already
# set, then simply executes a command without running another postgres
# instance.
runpg() {
    export PGDATA=$(mktemp -d ${TMPDIR-/tmp}/pgtmp.XXXXXXXX)
    export PGHOST="$PGDATA"
    export PGUSER=postgres

    trap cleanup 0 2 15

    # pick a random utf locale if we can as to increase
    # detection of encoding issues
    DB_LOC=`locale -a | grep -v '@latin' | grep -i utf | sort -R | head -1`
    if [ -z "$DB_LOC" ] ; then DB_LOC="--no-locale" ; else DB_LOC="--locale=$DB_LOC" ; fi

    echo Creating temporary PostgreSQL database cluster in "$PGDATA" with $DB_LOC

    $PGCTL init -s -o "$DB_LOC -U ${PGUSER-postgres} -A trust" \
        || return 1
    conf="$PGDATA/postgresql.conf"
    usd=$(sed -ne '/#\(unix_socket_director[^ ]*\) =.*/{
                    s//\1/p
                    q
                   }' "$conf")
    cat >> "$conf" <<EOF
$usd = '$PGDATA'
listen_addresses = ''
logging_collector = yes
fsync = no
synchronous_commit = off
full_page_writes = off
max_connections = 1000
EOF
    $PGCTL start -w -s &> /dev/null
}

setup_test() {
    runpg || return 1
    for i in $(seq $BASE_INSTANCE $((BASE_INSTANCE+14))) ''; do
        $PSQL -c "create database test$i;" &> /dev/null
    done
}

if test "$TEMP_POSTGRES" != 0; then
    if setup_test; then
        echo "PostgreSQL enabled for tests using temporary database cluster"
    else
        echo "Could not enable PostgreSQL"
        exit 1
    fi
else
    echo "PostgreSQL enabled for tests using existing database cluster"
fi

./stellar-core test $STELLAR_CORE_TEST_PARAMS --base-instance $BASE_INSTANCE "$TESTS" 2> /dev/null
R=$?
if [[ $R -ne 0 ]] ; then
    echo "Test failed, rerunning with debugger"
    echo ./stellar-core test $STELLAR_CORE_TEST_PARAMS --base-instance $BASE_INSTANCE "$TESTS"
    lldb -O 'settings set target.disable-aslr false' -o 'r'  -o 'bt' -o 'exit' -- ./stellar-core test $STELLAR_CORE_TEST_PARAMS --base-instance $BASE_INSTANCE "$TESTS"
fi
exit $R
