#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause

set -eo pipefail

source $DOCKER_BUILD_DIR/.ci/docker-prelude.sh

export CONFIGURE_OPTIONS=

if [ -d build ]; then
  rm -rf build
fi

if [ -d ./build-no-tests ]; then
  rm -rf build-no-tests
fi

if [ -d ./config_test ]; then
  rm -rf config_test
fi

if [ -z "$WITH_CRYPTO" ]; then
    echo "variable WITH_CRYPTO not set, defaulting to ossl"
    export WITH_CRYPTO="ossl"
fi

little_endian=$(echo -n I | od -to2 | awk 'FNR==1{ print substr($2,6,1)}')
if [ $little_endian -eq 0 ]; then
    export CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --with-integrationtcti=libtpms"
fi

if [ "$WITH_CRYPTO" != "ossl" ]; then
    export CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --disable-fapi --disable-policy"
fi

./bootstrap

# Is it a fuzz run, if so build the fuzz test and exit.
if [ "$GEN_FUZZ" == "1" ]; then
    ./configure --with-fuzzing=libfuzzer --enable-tcti-fuzzing \
      --disable-tcti-device --disable-tcti-mssim --disable-tcti-swtpm \
      --disable-shared --with-crypto="$WITH_CRYPTO"
    make -j$(nproc) check
    exit 0
fi

if [ "$TEST_TCTI_CONFIG" != "true" ]; then
#
# General build runs
#

# build with no tests enabled
mkdir ./build-no-tests
pushd ./build-no-tests

echo "PWD: $(pwd)"
echo "ls -la ../ $(ls -la ../)"

../configure --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
make -j$(nproc)
popd

if [ "$WITH_CRYPTO" == "none" ]; then
    echo "Exiting without running tests becuase crypto backend is none"
    exit 0
fi

# build with all tests enabled
mkdir ./build
pushd ./build

if [[ "$CC" == "gcc" && "$ENABLE_COVERAGE" == "true" ]]; then
    export CONFIGURE_OPTIONS="$CONFIGURE_OPTIONS --enable-code-coverage";
fi

if ldconfig -p 2>/dev/null| grep libasan > /dev/null && ldconfig -p 2>/dev/null| grep libubsan > /dev/null; then
  if [ $little_endian -eq 1 ]; then
    SANITIZER_OPTION="--with-sanitizer=undefined,address"
  fi
fi

if [ "$SCANBUILD" == "yes" ]; then
  scan-build --status-bugs ../configure --enable-unit --enable-self-generated-certificate --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
elif [ "$CC" == "clang" ]; then
  ../configure --enable-unit --enable-self-generated-certificate  --enable-integration --with-maxloglevel=none --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
else
  if [ "$WITH_TCTI" == "mssim" ]; then
    ../configure $SANITIZER_OPTION --disable-tcti-swtpm --enable-unit --enable-self-generated-certificate --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
  else
    ../configure $SANITIZER_OPTION --with-maxloglevel=none --enable-debug=yes --enable-unit --enable-self-generated-certificate --enable-integration --with-crypto=$WITH_CRYPTO $CONFIGURE_OPTIONS
  fi
fi

if [ "$SCANBUILD" == "yes" ]; then
  scan-build --status-bugs make -j
elif [ "$CC" == "clang" ]; then
  make -j distcheck
else
  make -j check
fi

popd

else # TEST_TCTI_CONFIG == true
mkdir ./config_test
pushd ./config_test
if [ "$CC" == "gcc" ]; then
  # No TCTI - expect to fail
  echo "========================== START TEST - NO TCTI =========================="
  (../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --disable-tcti-swtpm --disable-tcti-mssim --disable-tcti-device && exit 1) || echo "failed as expected";
  # only device TCTI
  echo "========================== START TEST - device TCTI =========================="
  mkdir -p ./dev/tpm0 && ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --disable-tcti-swtpm --disable-tcti-mssim --enable-tcti-device --with-device=./dev/tpm0
  make -j check TESTS="test/unit/tcti-device" && rm -rf ./dev
  # only mssim TCTI
  echo "========================== START TEST - mssim TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --disable-tcti-swtpm --enable-tcti-mssim --disable-tcti-device
  make -j check TESTS="test/unit/tcti-mssim"
  # device and mssim TCTIs
  echo "========================== START TEST - mssim & device TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --disable-tcti-swtpm --enable-tcti-mssim --enable-tcti-device
  make -j check TESTS="test/unit/tcti-device test/unit/tcti-mssim"
  # only swtmp TCTI
  echo "========================== START TEST - swtpm TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --enable-tcti-swtpm --disable-tcti-mssim --disable-tcti-device
  make -j check TESTS="test/unit/tcti-swtpm"
  # swtmp and device TCTIs
  echo "========================== START TEST - swtpm & device TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --enable-tcti-swtpm --disable-tcti-mssim --enable-tcti-device
  make -j check TESTS="test/unit/tcti-swtpm test/unit/tcti-device"
  # swtmp and mssim TCTIs
  echo "========================== START TEST - swtpm & mssim TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --enable-tcti-swtpm --enable-tcti-mssim --disable-tcti-device
  make -j check TESTS="test/unit/tcti-swtpm test/unit/tcti-mssim"
  # all TCTIs
  echo "========================== START TEST - swtpm & mssim & device TCTI =========================="
  ../configure --disable-doxygen-doc --enable-unit --enable-self-generated-certificate --enable-integration --enable-tcti-swtpm --enable-tcti-mssim --enable-tcti-device
  make -j check TESTS="test/unit/tcti-swtpm test/unit/tcti-mssim test/unit/tcti-device"
fi # CC == gcc
popd
fi # TEST_TCTI_CONFIG

# back in root git directory, check for whitespace errors. We do this post CI
# so people can verify the rest of their patch works in CI before dying.
# git diff --check fails with a non-zero return code causing the shell to die
# as it has a set -e executed.
if [ -n "$BASE_REF" ]; then
  echo "Running whitespace check"
  git fetch origin "$BASE_REF"
  git diff --check "origin/$BASE_REF"
fi

if [ "$ENABLE_COVERAGE" == "true" ]; then
    bash <(curl -s https://codecov.io/bash)
fi
exit 0
