// 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 SRC_GRAPHICS_LIB_MAGMA_SRC_MAGMA_UTIL_MACROS_H_
#define SRC_GRAPHICS_LIB_MAGMA_SRC_MAGMA_UTIL_MACROS_H_

#include <assert.h>
#include <limits.h>  // PAGE_SIZE
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

#include <limits>

// Files #including macros.h may assume that it #includes inttypes.h.
// So, for convenience, they don't need to follow "#include-what-you-use" for that header.
#include <inttypes.h>

#include "platform_logger.h"

#ifndef MAGMA_DEBUG_INTERNAL_USE_ONLY
#error MAGMA_DEBUG_INTERNAL_USE_ONLY not defined, your gn foo needs magma_util_config
#endif

namespace magma {

static constexpr bool kDebug = MAGMA_DEBUG_INTERNAL_USE_ONLY;

#define DASSERT(x)                                                                     \
  do {                                                                                 \
    if (magma::kDebug && !(x)) {                                                       \
      magma::PlatformLogger::Log(magma::PlatformLogger::LOG_ERROR, __FILE__, __LINE__, \
                                 "DASSERT: %s", #x);                                   \
      abort();                                                                         \
    }                                                                                  \
  } while (0)

#define DMESSAGE(format, ...)                                                                 \
  do {                                                                                        \
    if (magma::kDebug) {                                                                      \
      magma::PlatformLogger::Log(magma::PlatformLogger::LOG_INFO, __FILE__, __LINE__, format, \
                                 ##__VA_ARGS__);                                              \
    }                                                                                         \
  } while (0)

static constexpr bool kMagmaDretEnable = kDebug;

#define DRET(ret)                                                                     \
  (magma::kMagmaDretEnable && (ret) != 0                                              \
   ? magma::PlatformLogger::Log(magma::PlatformLogger::LOG_ERROR, __FILE__, __LINE__, \
                                "Returning error %" PRId64, (int64_t)(ret)),          \
   (ret) : (ret))

#define DRET_MSG(ret, format, ...)                                                      \
  (magma::kMagmaDretEnable && (ret) != 0                                                \
   ? magma::PlatformLogger::Log(magma::PlatformLogger::LOG_ERROR, __FILE__, __LINE__,   \
                                "Returning error %" PRId64 ": " format, (int64_t)(ret), \
                                ##__VA_ARGS__),                                         \
   (ret) : (ret))

#define DRETF(ret, format, ...)                                                       \
  (magma::kMagmaDretEnable && !(ret)                                                  \
   ? magma::PlatformLogger::Log(magma::PlatformLogger::LOG_ERROR, __FILE__, __LINE__, \
                                "Returning false: " format, ##__VA_ARGS__),           \
   (ret) : (ret))

#define DRETP(ret, format, ...)                                                       \
  (magma::kMagmaDretEnable && ((ret) == nullptr)                                      \
   ? magma::PlatformLogger::Log(magma::PlatformLogger::LOG_ERROR, __FILE__, __LINE__, \
                                "Returning null: " format, ##__VA_ARGS__),            \
   (ret) : (ret))

enum LogLevel { LOG_WARNING, LOG_INFO };

// TODO(fxbug.dev/13095) - replace with MAGMA_LOG
__attribute__((format(printf, 2, 3))) static inline void log(LogLevel level, const char* msg, ...) {
  switch (level) {
    case LOG_WARNING:
      printf("[WARNING] ");
      break;
    case LOG_INFO:
      printf("[INFO] ");
      break;
  }
  va_list args;
  va_start(args, msg);
  vprintf(msg, args);
  va_end(args);
  printf("\n");
}

#define UNIMPLEMENTED(...)                \
  do {                                    \
    DLOG("UNIMPLEMENTED: " #__VA_ARGS__); \
    DASSERT(false);                       \
  } while (0)

#define ATTRIBUTE_UNUSED __attribute__((unused))

#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&) = delete;      \
  void operator=(const TypeName&) = delete
#endif

static inline uint32_t to_uint32(uint64_t val) {
  DASSERT(val <= std::numeric_limits<uint32_t>::max());
  return static_cast<uint32_t>(val);
}

static inline uint32_t page_size() {
#ifdef PAGE_SIZE
  return PAGE_SIZE;
#else
  long page_size = sysconf(_SC_PAGESIZE);
  DASSERT(page_size > 0);
  return to_uint32(page_size);
#endif
}

static inline uint32_t page_shift() {
#if PAGE_SIZE == 4096
  return 12;
#else
  return __builtin_ctz(::magma::page_size());
#endif
}

static inline bool is_page_aligned(uint64_t val) { return (val & (::magma::page_size() - 1)) == 0; }

static inline uint32_t upper_32_bits(uint64_t n) { return static_cast<uint32_t>(n >> 32); }

static inline uint32_t lower_32_bits(uint64_t n) { return static_cast<uint32_t>(n); }

static inline bool get_pow2(uint64_t val, uint64_t* pow2_out) {
  if (val == 0)
    return DRETF(false, "zero is not a power of two");

  uint64_t result = 0;
  while ((val & 1) == 0) {
    val >>= 1;
    result++;
  }
  if (val >> 1)
    return DRETF(false, "not a power of 2");

  *pow2_out = result;
  return true;
}

static inline bool is_pow2(uint64_t val) {
  uint64_t out;
  return get_pow2(val, &out);
}

// Note, alignment must be a power of 2
template <class T, class U>
static inline T round_up(T val, U alignment) {
  DASSERT(is_pow2(alignment));
  return ((val - 1) | (alignment - 1)) + 1;
}

static inline uint64_t ns_to_ms(uint64_t ns) { return ns / 1000000ull; }

static inline int64_t ms_to_signed_ns(uint64_t ms) {
  if (ms > INT64_MAX / 1000000)
    return INT64_MAX;
  return static_cast<int64_t>(ms) * 1000000;
}

static inline uint64_t get_monotonic_ns() {
  timespec time;
  if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) {
    DASSERT(false);
    return 0;
  }
  return static_cast<uint64_t>(time.tv_sec) * 1000000000ull + time.tv_nsec;
}

#define MAGMA_THREAD_ANNOTATION(x) __attribute__((x))

#define MAGMA_CAPABILITY(x) MAGMA_THREAD_ANNOTATION(__capability__(x))
#define MAGMA_GUARDED(x) MAGMA_THREAD_ANNOTATION(__guarded_by__(x))
#define MAGMA_ACQUIRE(...) MAGMA_THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
#define MAGMA_TRY_ACQUIRE(...) MAGMA_THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
#define MAGMA_ACQUIRED_BEFORE(...) MAGMA_THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
#define MAGMA_ACQUIRED_AFTER(...) MAGMA_THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
#define MAGMA_RELEASE(...) MAGMA_THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
#define MAGMA_REQUIRES(...) MAGMA_THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
#define MAGMA_EXCLUDES(...) MAGMA_THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
#define MAGMA_RETURN_CAPABILITY(x) MAGMA_THREAD_ANNOTATION(__lock_returned__(x))
#define MAGMA_SCOPED_CAPABILITY MAGMA_THREAD_ANNOTATION(__scoped_lockable__)
#define MAGMA_NO_THREAD_SAFETY_ANALYSIS MAGMA_THREAD_ANNOTATION(__no_thread_safety_analysis__)

}  // namespace magma

#endif  // SRC_GRAPHICS_LIB_MAGMA_SRC_MAGMA_UTIL_MACROS_H_
