#pragma once

#include <string>
#include <fmt/core.h>
#include <functional>
#include <source_location>


namespace dbc {
  using std::string;

  class Error {
    public:
      const string message;
      Error(string m) : message{m} {}
      Error(const char *m) : message{m} {}
  };

  class CheckError : public Error {};
  class SentinelError : public Error {};
  class PreCondError : public Error {};
  class PostCondError : public Error {};

  void log(const string &message,
      const std::source_location location =
      std::source_location::current());

  [[noreturn]] void sentinel(const string &message,
      const std::source_location location =
      std::source_location::current());

  void pre(const string &message, bool test,
      const std::source_location location =
      std::source_location::current());

  void pre(const string &message, std::function<bool()> tester,
      const std::source_location location =
      std::source_location::current());

  void post(const string &message, bool test,
      const std::source_location location =
      std::source_location::current());

  void post(const string &message, std::function<bool()> tester,
      const std::source_location location =
      std::source_location::current());

  void check(bool test, const string &message,
      const std::source_location location =
      std::source_location::current());
}
