// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIB_SYSLOG_CPP_MACROS_H_
#define LIB_SYSLOG_CPP_MACROS_H_

#if defined(__Fuchsia__)
#include <zircon/types.h>
#endif

#include <lib/syslog/cpp/log_level.h>

#include <atomic>
#include <functional>
#include <limits>
#include <sstream>
#include <vector>

namespace syslog_backend {

struct LogBuffer;

#define WEAK __attribute__((weak))

#ifdef __Fuchsia__
WEAK void BeginRecordWithSocket(LogBuffer* buffer, syslog::LogSeverity severity,
                                const char* file_name, unsigned int line, const char* msg,
                                const char* condition, zx_handle_t socket);
WEAK void SetInterestChangedListener(void (*callback)(void* context, syslog::LogSeverity severity),
                                     void* context);
#endif
WEAK void BeginRecord(LogBuffer* buffer, syslog::LogSeverity severity, const char* file,
                      unsigned int line, const char* msg, const char* condition);

WEAK void WriteKeyValue(LogBuffer* buffer, const char* key, const char* value);

WEAK void WriteKeyValue(LogBuffer* buffer, const char* key, int64_t value);

WEAK void WriteKeyValue(LogBuffer* buffer, const char* key, uint64_t value);

WEAK void WriteKeyValue(LogBuffer* buffer, const char* key, double value);

WEAK void WriteKeyValue(LogBuffer* buffer, const char* key, bool value);

WEAK void EndRecord(LogBuffer* buffer);

WEAK bool FlushRecord(LogBuffer* buffer);

WEAK bool HasStructuredBackend();

#undef WEAK

template <typename... Args>
constexpr size_t ArgsSize(Args... args) {
  return sizeof...(args);
}

template <typename... Args>
struct Tuplet {
  std::tuple<Args...> tuple;
  size_t size;
  constexpr Tuplet(std::tuple<Args...> tuple, size_t size) : tuple(tuple), size(size) {}
};

template <typename Key, typename Value>
struct KeyValue {
  Key key;
  Value value;
  constexpr KeyValue(Key key, Value value) : key(key), value(value) {}
};

template <size_t i, size_t size>
constexpr bool ILessThanSize() {
  return i < size;
}

template <bool expr>
constexpr bool Not() {
  return !expr;
}

// Opaque structure representing the backend encode state.
// This structure only has meaning to the backend and application code shouldn't
// touch these values.
struct LogBuffer {
  // Max size of log buffer
  static constexpr auto kBufferSize = (1 << 15) / 8;
  // Additional storage for internal log state.
  static constexpr auto kStateSize = 13;
  // Record state (for keeping track of backend-specific details)
  uint64_t record_state[kStateSize];
  // Log data (used by the backend to encode the log into). The format
  // for this is backend-specific.
  uint64_t data[kBufferSize];

  // Does nothing (enabled when we hit the last parameter that the user passed into us)
  template <size_t i, size_t size, typename... T,
            typename std::enable_if<Not<ILessThanSize<i, size>()>(), int>::type = 0>
  void Encode(Tuplet<T...> value) {}

  // Encodes an int64
  void Encode(KeyValue<const char*, int64_t> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

#ifdef __APPLE__
  // Encodes a size_t. On Apple Clang, size_t is a special type.
  void Encode(KeyValue<const char*, size_t> value) {
    syslog_backend::WriteKeyValue(this, value.key, static_cast<int64_t>(value.value));
  }
#endif

  // Encodes an int
  void Encode(KeyValue<const char*, int32_t> value) {
    Encode(KeyValue<const char*, int64_t>(value.key, value.value));
  }

  // Encodes a uint32_t
  void Encode(KeyValue<const char*, uint32_t> value) {
    Encode(KeyValue<const char*, uint64_t>(value.key, value.value));
  }

  // Encodes an uint16_t
  void Encode(KeyValue<const char*, uint16_t> value) {
    Encode(KeyValue<const char*, uint64_t>(value.key, value.value));
  }

  // Encodes an int16_t
  void Encode(KeyValue<const char*, int16_t> value) {
    Encode(KeyValue<const char*, int64_t>(value.key, value.value));
  }

  // Encodes an uint64
  void Encode(KeyValue<const char*, uint64_t> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes a NULL-terminated C-string.
  void Encode(KeyValue<const char*, const char*> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes a NULL-terminated C-string.
  void Encode(KeyValue<const char*, char*> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes a double floating point value
  void Encode(KeyValue<const char*, double> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes a floating point value
  void Encode(KeyValue<const char*, float> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes a boolean value
  void Encode(KeyValue<const char*, bool> value) {
    syslog_backend::WriteKeyValue(this, value.key, value.value);
  }

  // Encodes an arbitrary list of values recursively.
  template <size_t i, size_t size, typename... T,
            typename std::enable_if<ILessThanSize<i, size>(), int>::type = 0>
  void Encode(Tuplet<T...> value) {
    auto val = std::get<i>(value.tuple);
    Encode(val);
    Encode<i + 1, size>(value);
  }
};
}  // namespace syslog_backend

namespace syslog {

class LogSeverityAndId {
 public:
  // Constructs a LogSeverityAndId with the given severity and an empty id.
  explicit constexpr LogSeverityAndId(LogSeverity severity) : severity_(severity), id_(nullptr) {}

  // Constructs a LogSeverityAndId with the given severity and id.
  constexpr LogSeverityAndId(LogSeverity severity, const char* id) : severity_(severity), id_(id) {}

  // Constructs a new LogSeverityAndId with the same severity but the given id.
  constexpr LogSeverityAndId operator()(const char* id) const {
    return LogSeverityAndId(severity_, id);
  }

  LogSeverity severity() const { return severity_; }

  const char* id() const { return id_; }

 private:
  const LogSeverity severity_;
  const char* const id_;
};

constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_TRACE(LOG_TRACE);
constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_DEBUG(LOG_DEBUG);
constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_INFO(LOG_INFO);
constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_WARNING(LOG_WARNING);
constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_ERROR(LOG_ERROR);
constexpr LogSeverityAndId LOG_SEVERITY_AND_ID_FATAL(LOG_FATAL);
inline LogSeverityAndId LOG_SEVERITY_AND_ID_LEVEL(int8_t level) { return LogSeverityAndId(level); }

template <typename... LogArgs>
constexpr syslog_backend::Tuplet<LogArgs...> Args(LogArgs... values) {
  return syslog_backend::Tuplet<LogArgs...>(std::make_tuple(values...), sizeof...(values));
}

template <typename Key, typename Value>
constexpr syslog_backend::KeyValue<Key, Value> KeyValueInternal(Key key, Value value) {
  return syslog_backend::KeyValue<Key, Value>(key, value);
}

// Used to denote a key-value pair for use in structured logging API calls.
// This macro exists solely to improve readability of calls to FX_SLOG
#define KV(a, b) a, b

template <typename Msg, typename... KeyValuePairs>
struct LogValue {
  constexpr LogValue(Msg msg, syslog_backend::Tuplet<KeyValuePairs...> kvps)
      : msg(msg), kvps(kvps) {}
  void LogNew(::syslog::LogSeverity severity, const char* file, unsigned int line,
              const char* condition) const {
    syslog_backend::LogBuffer buffer;
    syslog_backend::BeginRecord(&buffer, severity, file, line, msg, condition);
    // https://bugs.llvm.org/show_bug.cgi?id=41093 -- Clang loses constexpr
    // even though this should be constexpr here.
    buffer.Encode<0, sizeof...(KeyValuePairs)>(kvps);
    syslog_backend::EndRecord(&buffer);
    syslog_backend::FlushRecord(&buffer);
  }

  Msg msg;
  syslog_backend::Tuplet<KeyValuePairs...> kvps;
};

class LogMessageVoidify {
 public:
  void operator&(std::ostream&) {}
};

class LogMessage {
 public:
  LogMessage(LogSeverityAndId severity_and_id, const char* file, int line, const char* condition,
             const char* tag
#if defined(__Fuchsia__)
             ,
             zx_status_t status = std::numeric_limits<zx_status_t>::max()
#endif
  );
  LogMessage(LogSeverity severity, const char* file, int line, const char* condition,
             const char* tag
#if defined(__Fuchsia__)
             ,
             zx_status_t status = std::numeric_limits<zx_status_t>::max()
#endif
  );
  ~LogMessage();

  std::ostream& stream() { return stream_; }

 private:
  std::ostringstream stream_;
  const LogSeverity severity_;
  const char* const log_id_;
  const char* file_;
  const int line_;
  const char* condition_;
  const char* tag_;
#if defined(__Fuchsia__)
  const zx_status_t status_;
#endif
};

// LogFirstNState is used by the macro FX_LOGS_FIRST_N below.
class LogFirstNState {
 public:
  bool ShouldLog(uint32_t n);

 private:
  std::atomic<uint32_t> counter_{0};
};

// Gets the FX_VLOGS default verbosity level.
uint8_t GetVlogVerbosity();

// Returns true if |severity| is at or above the current minimum log level.
// LOG_FATAL and above is always true.
bool ShouldCreateLogMessage(LogSeverity severity);

// Returns true if severity is at or above the current minimum log level.
// LOG_FATAL and above is always true.
bool ShouldCreateLogMessage(const LogSeverityAndId& severity_and_id);

}  // namespace syslog

#define FX_LOG_STREAM(severity, tag)                                                               \
  ::syslog::LogMessage(::syslog::LOG_SEVERITY_AND_ID_##severity, __FILE__, __LINE__, nullptr, tag) \
      .stream()

#define FX_LOG_STREAM_STATUS(severity, status, tag)                                                \
  ::syslog::LogMessage(::syslog::LOG_SEVERITY_AND_ID_##severity, __FILE__, __LINE__, nullptr, tag, \
                       status)                                                                     \
      .stream()

#define FX_LAZY_STREAM(stream, condition) \
  !(condition) ? (void)0 : ::syslog::LogMessageVoidify() & (stream)

#define FX_EAT_STREAM_PARAMETERS(ignored) \
  true || (ignored)                       \
      ? (void)0                           \
      : ::syslog::LogMessageVoidify() &   \
            ::syslog::LogMessage(::syslog::LOG_FATAL, 0, 0, nullptr, nullptr).stream()

#define FX_LOG_IS_ON(severity) \
  (::syslog::ShouldCreateLogMessage(::syslog::LOG_SEVERITY_AND_ID_##severity))

#define FX_LOGS(severity) FX_LOGST(severity, nullptr)

#define FX_LOGST(severity, tag) FX_LAZY_STREAM(FX_LOG_STREAM(severity, tag), FX_LOG_IS_ON(severity))

#if defined(__Fuchsia__)
#define FX_PLOGST(severity, tag, status) \
  FX_LAZY_STREAM(FX_LOG_STREAM_STATUS(severity, status, tag), FX_LOG_IS_ON(severity))
#define FX_PLOGS(severity, status) FX_PLOGST(severity, nullptr, status)
#endif

// Writes a message to the global logger, the first |n| times that any callsite
// of this macro is invoked. |n| should be a positive integer literal.
// |severity| is one of INFO, WARNING, ERROR, FATAL
//
// Implementation notes:
// The outer for loop is a trick to allow us to introduce a new scope and
// introduce the variable |do_log| into that scope. It executes exactly once.
//
// The inner for loop is a trick to allow us to introduce a new scope and
// introduce the static variable |internal_state| into that new scope. It
// executes either zero or one times.
//
// C++ does not allow us to introduce two new variables into a single for loop
// scope and we need |do_log| so that the inner for loop doesn't execute twice.
#define FX_FIRST_N(n, log_statement)                                                            \
  for (bool do_log = true; do_log; do_log = false)                                              \
    for (static ::syslog::LogFirstNState internal_state; do_log && internal_state.ShouldLog(n); \
         do_log = false)                                                                        \
  log_statement
#define FX_LOGS_FIRST_N(severity, n) FX_FIRST_N(n, FX_LOGS(severity))
#define FX_LOGST_FIRST_N(severity, n, tag) FX_FIRST_N(n, FX_LOGST(severity, tag))

#define FX_CHECK(condition) FX_CHECKT(condition, nullptr)

#define FX_CHECKT(condition, tag)                                                              \
  FX_LAZY_STREAM(                                                                              \
      ::syslog::LogMessage(::syslog::LOG_FATAL, __FILE__, __LINE__, #condition, tag).stream(), \
      !(condition))

// The VLOG macros log with translated verbosities

// Get the severity corresponding to the given verbosity. Note that
// verbosity relative to the default severity and can be thought of
// as incrementally "more vebose than" the baseline.
syslog::LogSeverity GetSeverityFromVerbosity(uint8_t verbosity);

#define FX_VLOG_IS_ON(verbose_level) (verbose_level <= ::syslog::GetVlogVerbosity())

#define FX_VLOG_STREAM(verbose_level, tag)                                                        \
  ::syslog::LogMessage(GetSeverityFromVerbosity(verbose_level), __FILE__, __LINE__, nullptr, tag) \
      .stream()

#define FX_VLOGS(verbose_level) \
  FX_LAZY_STREAM(FX_VLOG_STREAM(verbose_level, nullptr), FX_VLOG_IS_ON(verbose_level))

#define FX_VLOGST(verbose_level, tag) \
  FX_LAZY_STREAM(FX_VLOG_STREAM(verbose_level, tag), FX_VLOG_IS_ON(verbose_level))

#ifndef NDEBUG
#define FX_DLOGS(severity) FX_LOGS(severity)
#define FX_DVLOGS(verbose_level) FX_VLOGS(verbose_level)
#define FX_DCHECK(condition) FX_CHECK(condition)
#else
#define FX_DLOGS(severity) FX_EAT_STREAM_PARAMETERS(true)
#define FX_DVLOGS(verbose_level) FX_EAT_STREAM_PARAMETERS(true)
#define FX_DCHECK(condition) FX_EAT_STREAM_PARAMETERS(condition)
#endif

#define FX_NOTREACHED() FX_DCHECK(false)

#define FX_NOTIMPLEMENTED() FX_LOGS(ERROR) << "Not implemented in: " << __PRETTY_FUNCTION__

template <typename Msg, typename... Args>
static auto MakeValue(Msg msg, syslog_backend::Tuplet<Args...> args) {
  return syslog::LogValue<Msg, Args...>(msg, args);
}

template <size_t i, size_t size, typename... Values, typename... Tuple,
          typename std::enable_if<syslog_backend::Not<syslog_backend::ILessThanSize<i, size>()>(),
                                  int>::type = 0>
static auto MakeKV(std::tuple<Values...> value, std::tuple<Tuple...> tuple) {
  return syslog_backend::Tuplet<Tuple...>(tuple, size);
}

template <size_t i, size_t size, typename... Values, typename... Tuple,
          typename std::enable_if<syslog_backend::ILessThanSize<i, size>(), int>::type = 0>
static auto MakeKV(std::tuple<Values...> value, std::tuple<Tuple...> tuple) {
  // Key at index i, value at index i+1
  auto k = std::get<i>(value);
  auto v = std::get<i + 1>(value);
  auto new_tuple = std::tuple_cat(tuple, std::make_tuple(syslog::KeyValueInternal(k, v)));
  return MakeKV<i + 2, size, Values...>(value, new_tuple);
}

template <typename... Args, typename... EmptyTuple>
static auto MakeKV(std::tuple<Args...> args, std::tuple<EmptyTuple...> start_tuple) {
  return MakeKV<0, sizeof...(Args), Args..., EmptyTuple...>(args, start_tuple);
}

template <typename... Args>
static auto MakeKV(std::tuple<Args...> args) {
  return MakeKV(args, std::make_tuple());
}

template <typename Msg, typename... Args>
static void fx_slog_internal(syslog::LogSeverity flag, const char* file, int line, Msg msg,
                             Args... args) {
  MakeValue(msg, MakeKV<Args...>(std::make_tuple(args...))).LogNew(flag, file, line, nullptr);
}

#define FX_SLOG_ETC(flag, args...)                      \
  do {                                                  \
    if (::syslog::ShouldCreateLogMessage(flag)) {       \
      fx_slog_internal(flag, __FILE__, __LINE__, args); \
    }                                                   \
  } while (0)

#define FX_SLOG(flag, msg...) FX_SLOG_ETC(::syslog::LOG_##flag, msg)

#endif  // LIB_SYSLOG_CPP_MACROS_H_
