// Copyright 2006-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.

#ifndef V8_LOG_UTILS_H_
#define V8_LOG_UTILS_H_

#include <stdio.h>

#include <cstdarg>

#include "src/allocation.h"
#include "src/base/compiler-specific.h"
#include "src/base/platform/mutex.h"
#include "src/flags.h"

namespace v8 {
namespace internal {

class Logger;

// Functions and data for performing output of log messages.
class Log {
 public:
  // Performs process-wide initialization.
  void Initialize(const char* log_file_name);

  // Disables logging, but preserves acquired resources.
  void stop() { is_stopped_ = true; }

  static bool InitLogAtStart() {
    return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc ||
           FLAG_log_handles || FLAG_log_suspect || FLAG_ll_prof ||
           FLAG_perf_basic_prof || FLAG_perf_prof ||
           FLAG_log_internal_timer_events || FLAG_prof_cpp;
  }

  // Frees all resources acquired in Initialize and Open... functions.
  // When a temporary file is used for the log, returns its stream descriptor,
  // leaving the file open.
  FILE* Close();

  // Returns whether logging is enabled.
  bool IsEnabled() {
    return !is_stopped_ && output_handle_ != NULL;
  }

  // Size of buffer used for formatting log messages.
  static const int kMessageBufferSize = 2048;

  // This mode is only used in tests, as temporary files are automatically
  // deleted on close and thus can't be accessed afterwards.
  static const char* const kLogToTemporaryFile;
  static const char* const kLogToConsole;

  // Utility class for formatting log messages. It fills the message into the
  // static buffer in Log.
  class MessageBuilder BASE_EMBEDDED {
   public:
    // Create a message builder starting from position 0.
    // This acquires the mutex in the log as well.
    explicit MessageBuilder(Log* log);
    ~MessageBuilder() { }

    // Append string data to the log message.
    void PRINTF_FORMAT(2, 3) Append(const char* format, ...);

    // Append string data to the log message.
    void PRINTF_FORMAT(2, 0) AppendVA(const char* format, va_list args);

    // Append a character to the log message.
    void Append(const char c);

    // Append double quoted string to the log message.
    void AppendDoubleQuotedString(const char* string);

    // Append a heap string.
    void Append(String* str);

    // Appends an address.
    void AppendAddress(Address addr);

    void AppendSymbolName(Symbol* symbol);

    void AppendDetailed(String* str, bool show_impl_info);

    // Append a portion of a string.
    void AppendStringPart(const char* str, int len);

    // Write the log message to the log file currently opened.
    void WriteToLogFile();

   private:
    Log* log_;
    base::LockGuard<base::Mutex> lock_guard_;
    int pos_;
  };

 private:
  explicit Log(Logger* logger);

  // Opens stdout for logging.
  void OpenStdout();

  // Opens file for logging.
  void OpenFile(const char* name);

  // Opens a temporary file for logging.
  void OpenTemporaryFile();

  // Implementation of writing to a log file.
  int WriteToFile(const char* msg, int length) {
    DCHECK(output_handle_ != NULL);
    size_t rv = fwrite(msg, 1, length, output_handle_);
    DCHECK(static_cast<size_t>(length) == rv);
    USE(rv);
    fflush(output_handle_);
    return length;
  }

  // Whether logging is stopped (e.g. due to insufficient resources).
  bool is_stopped_;

  // When logging is active output_handle_ is used to store a pointer to log
  // destination.  mutex_ should be acquired before using output_handle_.
  FILE* output_handle_;

  // mutex_ is a Mutex used for enforcing exclusive
  // access to the formatting buffer and the log file or log memory buffer.
  base::Mutex mutex_;

  // Buffer used for formatting log messages. This is a singleton buffer and
  // mutex_ should be acquired before using it.
  char* message_buffer_;

  Logger* logger_;

  friend class Logger;
};


}  // namespace internal
}  // namespace v8

#endif  // V8_LOG_UTILS_H_
