#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_all.hpp>

#include <utils/BuildInfo.hpp>
#include <utils/Stringify.hpp>
#include <utils/pugs_build_info.hpp>
#include <utils/pugs_config.hpp>

#include <sstream>

#ifdef PUGS_HAS_MPI
#include <mpi.h>
#endif   //  PUGS_HAS_MPI

#ifdef PUGS_HAS_PETSC
#include <petsc.h>
#endif   // PUGS_HAS_PETSC

// clazy:excludeall=non-pod-global-static

TEST_CASE("BuildInfo", "[utils]")
{
  SECTION("type")
  {
    REQUIRE(BuildInfo::type() == PUGS_BUILD_TYPE);
  }

  SECTION("compiler")
  {
    std::stringstream compiler_info;
    compiler_info << PUGS_BUILD_COMPILER << " (" << PUGS_BUILD_COMPILER_VERSION << ")";
    REQUIRE(BuildInfo::compiler() == compiler_info.str());
  }

  SECTION("kokkos")
  {
    REQUIRE(BuildInfo::kokkosDevices() == PUGS_BUILD_KOKKOS_DEVICES);
  }

  SECTION("mpi")
  {
#ifdef PUGS_HAS_MPI
    const std::string mpi_library = []() {
      int length;
      char mpi_version[MPI_MAX_LIBRARY_VERSION_STRING];
      MPI_Get_library_version(mpi_version, &length);
      return std::string(mpi_version);
    }();

    REQUIRE(BuildInfo::mpiLibrary() == mpi_library);
#else
    REQUIRE(BuildInfo::mpiLibrary() == "none");
#endif   // PUGS_HAS_MPI
  }

  SECTION("petsc")
  {
#ifdef PUGS_HAS_PETSC
    const std::string petsc_library =
      stringify(PETSC_VERSION_MAJOR) + "." + stringify(PETSC_VERSION_MINOR) + "." + stringify(PETSC_VERSION_SUBMINOR);

    REQUIRE(BuildInfo::petscLibrary() == petsc_library);
#else
    REQUIRE(BuildInfo::petscLibrary() == "none");
#endif   // PUGS_HAS_PETSC
  }
}