#!/usr/bin/env bash

set -o errexit
set -o pipefail

declare working_dir
working_dir="$(pwd)"

declare base current
base="$(cat base-commit.txt)"
current="$(cat current-commit.txt)"

export PATH
PATH="${working_dir:?}/install/bin:${PATH:-}"

# Remove 'r' prefix in version string.
declare old_ver new_ver
old_ver="${base:1}-base"
new_ver="${current:1}-current"

command -V abi-compliance-checker >/dev/null

mkdir cxx-abi cxx-noabi

# Generate XML descriptors with sections used by both old and new tests.
if true; then
  cat >old.xml <<DOC
<version>
  ${old_ver:?}
</version>

<libs>
  ../install/old/lib
</libs>

<add_include_paths>
  ../install/old/include/
</add_include_paths>

<skip_including>
  /v_noabi/bsoncxx/enums/
  /v_noabi/bsoncxx/config/
  /v_noabi/mongocxx/config/
  /v1/detail/prelude.hpp
  /v1/detail/postlude.hpp
</skip_including>

DOC

  cat >new.xml <<DOC
<version>
  ${new_ver:?}
</version>

<libs>
  ../install/new/lib
</libs>

<add_include_paths>
  ../install/new/include/
</add_include_paths>

<skip_including>
  /v_noabi/bsoncxx/enums/
  /v_noabi/bsoncxx/config/
  /v_noabi/mongocxx/config/
  /v1/detail/prelude.hpp
  /v1/detail/postlude.hpp
</skip_including>

DOC

  tee cxx-abi/old.xml cxx-noabi/old.xml <old.xml >/dev/null
  tee cxx-abi/new.xml cxx-noabi/new.xml <new.xml >/dev/null
  rm old.xml new.xml
fi

# Append sections specific to each ABI test.
if true; then
  cat >>cxx-abi/old.xml <<DOC
<headers>
  ../install/old/include/bsoncxx/
  ../install/old/include/mongocxx/
</headers>

<skip_headers>
  /v_noabi/
</skip_headers>

<skip_namespaces>
  bsoncxx::detail
  mongocxx::detail
</skip_namespaces>
DOC

  cat >>cxx-abi/new.xml <<DOC
<headers>
  ../install/new/include/mongocxx/
  ../install/new/include/bsoncxx/
</headers>

<skip_headers>
  /v_noabi/
</skip_headers>

<skip_namespaces>
  bsoncxx::detail
  mongocxx::detail
</skip_headers>
DOC

  cat >>cxx-noabi/old.xml <<DOC
<headers>
  ../install/old/include/bsoncxx/v_noabi
  ../install/old/include/mongocxx/v_noabi
</headers>

<skip_namespaces>
  bsoncxx::detail
  mongocxx::detail
  bsoncxx::v1
  mongocxx::v1
</skip_namespaces>
DOC

  cat >>cxx-noabi/new.xml <<DOC
<headers>
  ../install/new/include/bsoncxx/v_noabi
  ../install/new/include/mongocxx/v_noabi
</headers>

<skip_namespaces>
  bsoncxx::detail
  mongocxx::detail
  bsoncxx::v1
  mongocxx::v1
</skip_namespaces>
DOC
fi

args=(
  -lib mongo-cxx-driver
  -old old.xml
  -new new.xml
)

# Allow task to upload the HTML report despite failed status.
echo "Generating stable ABI report..."
pushd cxx-abi
declare ret
abi-compliance-checker "${args[@]}" 2>&1 && ret="$?" || ret="$?"
if [[ "${ret:?}" -gt 1 ]]; then
  declare status
  status='{"status":"failed", "type":"test", "should_continue":true, "desc":"abi-compliance-checker emitted one or more errors"}'
  curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true
elif [[ "${ret:?}" -gt 0 ]]; then
  declare status
  status='{"status":"failed", "type":"test", "should_continue":true, "desc":"detected stable ABI incompatibility"}'
  curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true
fi
popd # cxx-abi
echo "Generating stable ABI report... done."

# Also create a report for the unstable ABI. Errors are expected and OK.
echo "Generating unstable ABI report..."
pushd cxx-noabi
declare ret
abi-compliance-checker "${args[@]}" 2>&1 && ret="$?" || ret="$?"
if [[ "${ret:?}" -gt 1 ]]; then
  declare status
  status='{"status":"failed", "type":"test", "should_continue":true, "desc":"abi-compliance-checker emitted one or more errors"}'
  curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true
fi
popd # cxx-noabi
echo "Generating unstable ABI report... done."
