/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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.
 */

#ifndef ART_RUNTIME_BASE_LOGGING_H_
#define ART_RUNTIME_BASE_LOGGING_H_

#include <cerrno>
#include <cstring>
#include <iostream>  // NOLINT
#include <sstream>
#include <signal.h>
#include "base/macros.h"
#include "log_severity.h"

#define CHECK(x) \
  if (UNLIKELY(!(x))) \
    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
        << "Check failed: " #x << " "

#define CHECK_OP(LHS, RHS, OP) \
  for (::art::EagerEvaluator<typeof(LHS), typeof(RHS)> _values(LHS, RHS); \
       UNLIKELY(!(_values.lhs OP _values.rhs)); /* empty */) \
    ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
        << "Check failed: " << #LHS << " " << #OP << " " << #RHS \
        << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "

#define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
#define CHECK_NE(x, y) CHECK_OP(x, y, !=)
#define CHECK_LE(x, y) CHECK_OP(x, y, <=)
#define CHECK_LT(x, y) CHECK_OP(x, y, <)
#define CHECK_GE(x, y) CHECK_OP(x, y, >=)
#define CHECK_GT(x, y) CHECK_OP(x, y, >)

#define CHECK_STROP(s1, s2, sense) \
  if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \
    LOG(FATAL) << "Check failed: " \
               << "\"" << s1 << "\"" \
               << (sense ? " == " : " != ") \
               << "\"" << s2 << "\""

#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)

#define CHECK_PTHREAD_CALL(call, args, what) \
  do { \
    int rc = call args; \
    if (rc != 0) { \
      errno = rc; \
      PLOG(FATAL) << # call << " failed for " << what; \
    } \
  } while (false)

#ifndef NDEBUG

#define DCHECK(x) CHECK(x)
#define DCHECK_EQ(x, y) CHECK_EQ(x, y)
#define DCHECK_NE(x, y) CHECK_NE(x, y)
#define DCHECK_LE(x, y) CHECK_LE(x, y)
#define DCHECK_LT(x, y) CHECK_LT(x, y)
#define DCHECK_GE(x, y) CHECK_GE(x, y)
#define DCHECK_GT(x, y) CHECK_GT(x, y)
#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)

#else  // NDEBUG

#define DCHECK(condition) \
  while (false) \
    CHECK(condition)

#define DCHECK_EQ(val1, val2) \
  while (false) \
    CHECK_EQ(val1, val2)

#define DCHECK_NE(val1, val2) \
  while (false) \
    CHECK_NE(val1, val2)

#define DCHECK_LE(val1, val2) \
  while (false) \
    CHECK_LE(val1, val2)

#define DCHECK_LT(val1, val2) \
  while (false) \
    CHECK_LT(val1, val2)

#define DCHECK_GE(val1, val2) \
  while (false) \
    CHECK_GE(val1, val2)

#define DCHECK_GT(val1, val2) \
  while (false) \
    CHECK_GT(val1, val2)

#define DCHECK_STREQ(str1, str2) \
  while (false) \
    CHECK_STREQ(str1, str2)

#define DCHECK_STRNE(str1, str2) \
  while (false) \
    CHECK_STRNE(str1, str2)

#endif

#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()

#define LG LOG(INFO)

#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "

#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
#define VLOG(module) if (VLOG_IS_ON(module)) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()

//
// Implementation details beyond this point.
//

namespace art {

template <typename LHS, typename RHS>
struct EagerEvaluator {
  EagerEvaluator(LHS lhs, RHS rhs) : lhs(lhs), rhs(rhs) { }
  LHS lhs;
  RHS rhs;
};

// We want char*s to be treated as pointers, not strings. If you want them treated like strings,
// you'd need to use CHECK_STREQ and CHECK_STRNE anyway to compare the characters rather than their
// addresses. We could express this more succinctly with std::remove_const, but this is quick and
// easy to understand, and works before we have C++0x. We rely on signed/unsigned warnings to
// protect you against combinations not explicitly listed below.
#define EAGER_PTR_EVALUATOR(T1, T2) \
  template <> struct EagerEvaluator<T1, T2> { \
    EagerEvaluator(T1 lhs, T2 rhs) \
        : lhs(reinterpret_cast<const void*>(lhs)), \
          rhs(reinterpret_cast<const void*>(rhs)) { } \
    const void* lhs; \
    const void* rhs; \
  }
EAGER_PTR_EVALUATOR(const char*, const char*);
EAGER_PTR_EVALUATOR(const char*, char*);
EAGER_PTR_EVALUATOR(char*, const char*);
EAGER_PTR_EVALUATOR(char*, char*);
EAGER_PTR_EVALUATOR(const unsigned char*, const unsigned char*);
EAGER_PTR_EVALUATOR(const unsigned char*, unsigned char*);
EAGER_PTR_EVALUATOR(unsigned char*, const unsigned char*);
EAGER_PTR_EVALUATOR(unsigned char*, unsigned char*);
EAGER_PTR_EVALUATOR(const signed char*, const signed char*);
EAGER_PTR_EVALUATOR(const signed char*, signed char*);
EAGER_PTR_EVALUATOR(signed char*, const signed char*);
EAGER_PTR_EVALUATOR(signed char*, signed char*);

// This indirection greatly reduces the stack impact of having
// lots of checks/logging in a function.
struct LogMessageData {
 public:
  LogMessageData(const char* file, int line, LogSeverity severity, int error);
  std::ostringstream buffer;
  const char* const file;
  const int line_number;
  const LogSeverity severity;
  const int error;

 private:
  DISALLOW_COPY_AND_ASSIGN(LogMessageData);
};

class LogMessage {
 public:
  LogMessage(const char* file, int line, LogSeverity severity, int error)
    : data_(new LogMessageData(file, line, severity, error)) {
  }

  ~LogMessage() LOCKS_EXCLUDED(Locks::logging_lock_);

  std::ostream& stream() {
    return data_->buffer;
  }

 private:
  static void LogLine(const LogMessageData& data, const char*);

  LogMessageData* const data_;

  friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
  friend class Mutex;
  DISALLOW_COPY_AND_ASSIGN(LogMessage);
};

// Prints a hex dump in this format:
//
// 01234560: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
// 01234568: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
class HexDump {
 public:
  HexDump(const void* address, size_t byte_count, bool show_actual_addresses = false);
  void Dump(std::ostream& os) const;

 private:
  const void* address_;
  size_t byte_count_;
  bool show_actual_addresses_;

  DISALLOW_COPY_AND_ASSIGN(HexDump);
};
std::ostream& operator<<(std::ostream& os, const HexDump& rhs);

// A convenience to allow any class with a "Dump(std::ostream& os)" member function
// but without an operator<< to be used as if it had an operator<<. Use like this:
//
//   os << Dumpable<MyType>(my_type_instance);
//
template<typename T>
class Dumpable {
 public:
  explicit Dumpable(T& value) : value_(value) {
  }

  void Dump(std::ostream& os) const {
    value_.Dump(os);
  }

 private:
  T& value_;

  DISALLOW_COPY_AND_ASSIGN(Dumpable);
};

template<typename T>
std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
  rhs.Dump(os);
  return os;
}

template<typename T>
class MutatorLockedDumpable {
 public:
  explicit MutatorLockedDumpable(T& value)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : value_(value) {
  }

  void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    value_.Dump(os);
  }

 private:
  T& value_;

  DISALLOW_COPY_AND_ASSIGN(MutatorLockedDumpable);
};

template<typename T>
std::ostream& operator<<(std::ostream& os, const MutatorLockedDumpable<T>& rhs)
// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) however annotalysis
//       currently fails for this.
    NO_THREAD_SAFETY_ANALYSIS {
  rhs.Dump(os);
  return os;
}

// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
// format strings.
template<typename T>
class ToStr {
 public:
  explicit ToStr(const T& value) {
    std::ostringstream os;
    os << value;
    s_ = os.str();
  }

  const char* c_str() const {
    return s_.c_str();
  }

  const std::string& str() const {
    return s_;
  }

 private:
  std::string s_;
  DISALLOW_COPY_AND_ASSIGN(ToStr);
};

// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
// and the "-verbose:" command line argument.
struct LogVerbosity {
  bool class_linker;  // Enabled with "-verbose:class".
  bool compiler;
  bool heap;
  bool gc;
  bool jdwp;
  bool jni;
  bool monitor;
  bool startup;
  bool third_party_jni;  // Enabled with "-verbose:third-party-jni".
  bool threads;
};

extern LogVerbosity gLogVerbosity;

// Used on fatal exit. Prevents recursive aborts. Allows us to disable
// some error checking to ensure fatal shutdown makes forward progress.
extern unsigned int gAborting;

extern void InitLogging(char* argv[]);

extern const char* GetCmdLine();
extern const char* ProgramInvocationName();
extern const char* ProgramInvocationShortName();

}  // namespace art

#endif  // ART_RUNTIME_BASE_LOGGING_H_
