// Copyright 2009 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/logging/log-utils.h"

#include <atomic>
#include <memory>

#include "src/base/platform/mutex.h"
#include "src/base/platform/platform.h"
#include "src/common/assert-scope.h"
#include "src/objects/objects-inl.h"
#include "src/strings/string-stream.h"
#include "src/utils/utils.h"
#include "src/utils/vector.h"
#include "src/utils/version.h"

namespace v8 {
namespace internal {

const char* const Log::kLogToTemporaryFile = "+";
const char* const Log::kLogToConsole = "-";

// static
FILE* Log::CreateOutputHandle(std::string file_name) {
  // If we're logging anything, we need to open the log file.
  if (!Log::InitLogAtStart()) {
    return nullptr;
  } else if (Log::IsLoggingToConsole(file_name)) {
    return stdout;
  } else if (Log::IsLoggingToTemporaryFile(file_name)) {
    return base::OS::OpenTemporaryFile();
  } else {
    return base::OS::FOpen(file_name.c_str(), base::OS::LogFileOpenMode);
  }
}

// static
bool Log::IsLoggingToConsole(std::string file_name) {
  return file_name.compare(Log::kLogToConsole) == 0;
}

// static
bool Log::IsLoggingToTemporaryFile(std::string file_name) {
  return file_name.compare(Log::kLogToTemporaryFile) == 0;
}

Log::Log(Logger* logger, std::string file_name)
    : logger_(logger),
      file_name_(file_name),
      output_handle_(Log::CreateOutputHandle(file_name)),
      os_(output_handle_ == nullptr ? stdout : output_handle_),
      format_buffer_(NewArray<char>(kMessageBufferSize)) {
  if (output_handle_) WriteLogHeader();
}

void Log::WriteLogHeader() {
  Log::MessageBuilder msg(this);
  LogSeparator kNext = LogSeparator::kSeparator;
  msg << "v8-version" << kNext << Version::GetMajor() << kNext
      << Version::GetMinor() << kNext << Version::GetBuild() << kNext
      << Version::GetPatch();
  if (strlen(Version::GetEmbedder()) != 0) {
    msg << kNext << Version::GetEmbedder();
  }
  msg << kNext << Version::IsCandidate();
  msg.WriteToLogFile();
}

std::unique_ptr<Log::MessageBuilder> Log::NewMessageBuilder() {
  // Fast check of is_logging() without taking the lock. Bail out immediately if
  // logging isn't enabled.
  if (!logger_->is_logging()) return {};

  std::unique_ptr<Log::MessageBuilder> result(new Log::MessageBuilder(this));

  // The first invocation of is_logging() might still read an old value. It is
  // fine if a background thread starts logging a bit later, but we want to
  // avoid background threads continue logging after logging was already closed.
  if (!logger_->is_logging()) return {};
  DCHECK_NOT_NULL(format_buffer_.get());

  return result;
}

FILE* Log::Close() {
  FILE* result = nullptr;
#if V8_OS_STARBOARD
  SB_NOTIMPLEMENTED();
#else
  if (output_handle_ != nullptr) {
    fflush(output_handle_);
    result = output_handle_;
  }
#endif
  output_handle_ = nullptr;
  format_buffer_.reset();
  return result;
}

std::string Log::file_name() const { return file_name_; }

Log::MessageBuilder::MessageBuilder(Log* log)
    : log_(log), lock_guard_(&log_->mutex_) {
}

void Log::MessageBuilder::AppendString(String str,
                                       base::Optional<int> length_limit) {
  if (str.is_null()) return;

  DisallowHeapAllocation no_gc;  // Ensure string stays valid.
  int length = str.length();
  if (length_limit) length = std::min(length, *length_limit);
  for (int i = 0; i < length; i++) {
    uint16_t c = str.Get(i);
    if (c <= 0xFF) {
      AppendCharacter(static_cast<char>(c));
    } else {
      // Escape non-ascii characters.
      AppendRawFormatString("\\u%04x", c & 0xFFFF);
    }
  }
}

void Log::MessageBuilder::AppendString(Vector<const char> str) {
  for (auto i = str.begin(); i < str.end(); i++) AppendCharacter(*i);
}

void Log::MessageBuilder::AppendString(const char* str) {
  if (str == nullptr) return;
  AppendString(str, strlen(str));
}

void Log::MessageBuilder::AppendString(const char* str, size_t length,
                                       bool is_one_byte) {
  if (str == nullptr) return;
  if (is_one_byte) {
    for (size_t i = 0; i < length; i++) {
      DCHECK_IMPLIES(is_one_byte, str[i] != '\0');
      AppendCharacter(str[i]);
    }
  } else {
    DCHECK_EQ(length % 2, 0);
    for (size_t i = 0; i + 1 < length; i += 2) {
      AppendTwoByteCharacter(str[i], str[i + 1]);
    }
  }
}

void Log::MessageBuilder::AppendFormatString(const char* format, ...) {
  va_list args;
  va_start(args, format);
  const int length = FormatStringIntoBuffer(format, args);
  va_end(args);
  for (int i = 0; i < length; i++) {
    DCHECK_NE(log_->format_buffer_[i], '\0');
    AppendCharacter(log_->format_buffer_[i]);
  }
}

void Log::MessageBuilder::AppendTwoByteCharacter(char c1, char c2) {
  if (c2 == 0) {
    AppendCharacter(c1);
  } else {
    // Escape non-printable characters.
    AppendRawFormatString("\\u%02x%02x", c1 & 0xFF, c2 & 0xFF);
  }
}
void Log::MessageBuilder::AppendCharacter(char c) {
  if (c >= 32 && c <= 126) {
    if (c == ',') {
      // Escape commas to avoid adding column separators.
      AppendRawFormatString("\\x2C");
    } else if (c == '\\') {
      AppendRawFormatString("\\\\");
    } else {
      // Safe, printable ascii character.
      AppendRawCharacter(c);
    }
  } else if (c == '\n') {
    // Escape newlines to avoid adding row separators.
    AppendRawFormatString("\\n");
  } else {
    // Escape non-printable characters.
    AppendRawFormatString("\\x%02x", c & 0xFF);
  }
}

void Log::MessageBuilder::AppendSymbolName(Symbol symbol) {
  DCHECK(!symbol.is_null());
  OFStream& os = log_->os_;
  os << "symbol(";
  if (!symbol.description().IsUndefined()) {
    os << "\"";
    AppendSymbolNameDetails(String::cast(symbol.description()), false);
    os << "\" ";
  }
  os << "hash " << std::hex << symbol.Hash() << std::dec << ")";
}

void Log::MessageBuilder::AppendSymbolNameDetails(String str,
                                                  bool show_impl_info) {
  if (str.is_null()) return;

  DisallowHeapAllocation no_gc;  // Ensure string stays valid.
  OFStream& os = log_->os_;
  int limit = str.length();
  if (limit > 0x1000) limit = 0x1000;
  if (show_impl_info) {
    os << (str.IsOneByteRepresentation() ? 'a' : '2');
    if (StringShape(str).IsExternal()) os << 'e';
    if (StringShape(str).IsInternalized()) os << '#';
    os << ':' << str.length() << ':';
  }
  AppendString(str, limit);
}

int Log::MessageBuilder::FormatStringIntoBuffer(const char* format,
                                                va_list args) {
  Vector<char> buf(log_->format_buffer_.get(), Log::kMessageBufferSize);
  int length = v8::internal::VSNPrintF(buf, format, args);
  // |length| is -1 if output was truncated.
  if (length == -1) length = Log::kMessageBufferSize;
  DCHECK_LE(length, Log::kMessageBufferSize);
  DCHECK_GE(length, 0);
  return length;
}

void Log::MessageBuilder::AppendRawFormatString(const char* format, ...) {
  va_list args;
  va_start(args, format);
  const int length = FormatStringIntoBuffer(format, args);
  va_end(args);
  for (int i = 0; i < length; i++) {
    DCHECK_NE(log_->format_buffer_[i], '\0');
    AppendRawCharacter(log_->format_buffer_[i]);
  }
}

#if defined(V8_OS_STARBOARD)
void Log::MessageBuilder::AppendRawCharacter(char c) {}
#else
void Log::MessageBuilder::AppendRawCharacter(char c) { log_->os_ << c; }
#endif

#if defined(V8_OS_STARBOARD)
void Log::MessageBuilder::WriteToLogFile() {}
#else
void Log::MessageBuilder::WriteToLogFile() {
  log_->os_ << std::endl;
}
#endif

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<const char*>(
    const char* string) {
  this->AppendString(string);
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<void*>(void* pointer) {
#if !defined(V8_OS_STARBOARD)
  OFStream& os = log_->os_;
  // Manually format the pointer since on Windows we do not consistently
  // get a "0x" prefix.
  os << "0x" << std::hex << reinterpret_cast<intptr_t>(pointer) << std::dec;
#endif
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<char>(char c) {
  this->AppendCharacter(c);
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<String>(String string) {
  this->AppendString(string);
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<Symbol>(Symbol symbol) {
  this->AppendSymbolName(symbol);
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<Name>(Name name) {
  if (name.IsString()) {
    this->AppendString(String::cast(name));
  } else {
    this->AppendSymbolName(Symbol::cast(name));
  }
  return *this;
}

template <>
Log::MessageBuilder& Log::MessageBuilder::operator<<<LogSeparator>(
    LogSeparator separator) {
  // Skip escaping to create a new column.
  this->AppendRawCharacter(',');
  return *this;
}

}  // namespace internal
}  // namespace v8
