/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#ifndef GEODE_ASSERT_H_
#define GEODE_ASSERT_H_

#include <geode/internal/geode_globals.hpp>

/**
 * @file
 *
 *  Assertion functions for debugging
 */

namespace apache {
namespace geode {
namespace client {

/**
 * @class Assert Assert.hpp
 *
 * Declares debugging assertion reporting functions.
 */
class APACHE_GEODE_EXPORT Assert {
 public:
  /** If the given expression is true, does nothing, otherwise calls
   * @ref throwAssertion .
   */
  inline static void assertTrue(bool expression, const char* expressionText,
                                const char* file, int line) {
    if (!expression) {
      throwAssertion(expressionText, file, line);
    }
  }

  /** Throws the given assertion.
   */
  [[noreturn]] static void throwAssertion(const char* expressionText,
                                          const char* file, int line);
};
}  // namespace client
}  // namespace geode
}  // namespace apache

/** Throws the given assertion. */
#define GF_R_ASSERT(x) \
  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)

#ifndef GF_DEBUG_ASSERTS
/** Change this to 1 to use assertion functions. */
#define GF_DEBUG_ASSERTS 0
#endif

#ifndef GF_DEVEL_ASSERTS
#define GF_DEVEL_ASSERTS 0
#endif

#if GF_DEVEL_ASSERTS == 1
#undef GF_DEBUG_ASSERTS
#define GF_DEBUG_ASSERTS 1
#endif

#if GF_DEBUG_ASSERTS == 1
#undef GF_DEVEL_ASSERTS
#define GF_DEVEL_ASSERTS 1
#endif

/** Throws the given assertion if GF_DEBUG_ASSERTS is true. */
#if GF_DEBUG_ASSERTS == 1
#define GF_D_ASSERT(x) \
  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)
#else
#define GF_D_ASSERT(x)
#endif

/** Throws the given assertion if GF_DEVEL_ASSERTS is true. */
#if GF_DEVEL_ASSERTS == 1
#define GF_DEV_ASSERT(x) \
  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)
#else
#define GF_DEV_ASSERT(x)
#endif

#endif  // GEODE_ASSERT_H_
