// Copyright 2014 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_STRING_STREAM_H_
#define V8_STRING_STREAM_H_

#include <memory>

#include "src/allocation.h"
#include "src/handles.h"
#include "src/vector.h"

namespace v8 {
namespace internal {

// Forward declarations.
class ByteArray;

class StringAllocator {
 public:
  virtual ~StringAllocator() { }
  // Allocate a number of bytes.
  virtual char* allocate(unsigned bytes) = 0;
  // Allocate a larger number of bytes and copy the old buffer to the new one.
  // bytes is an input and output parameter passing the old size of the buffer
  // and returning the new size.  If allocation fails then we return the old
  // buffer and do not increase the size.
  virtual char* grow(unsigned* bytes) = 0;
};


// Normal allocator uses new[] and delete[].
class HeapStringAllocator final : public StringAllocator {
 public:
  ~HeapStringAllocator() { DeleteArray(space_); }
  char* allocate(unsigned bytes) override;
  char* grow(unsigned* bytes) override;

 private:
  char* space_;
};


class FixedStringAllocator final : public StringAllocator {
 public:
  FixedStringAllocator(char* buffer, unsigned length)
      : buffer_(buffer), length_(length) {}
  ~FixedStringAllocator() override{};
  char* allocate(unsigned bytes) override;
  char* grow(unsigned* bytes) override;

 private:
  char* buffer_;
  unsigned length_;
  DISALLOW_COPY_AND_ASSIGN(FixedStringAllocator);
};


class FmtElm final {
 public:
  FmtElm(int value) : type_(INT) {  // NOLINT
    data_.u_int_ = value;
  }
  explicit FmtElm(double value) : type_(DOUBLE) {
    data_.u_double_ = value;
  }
  FmtElm(const char* value) : type_(C_STR) {  // NOLINT
    data_.u_c_str_ = value;
  }
  FmtElm(const Vector<const uc16>& value) : type_(LC_STR) {  // NOLINT
    data_.u_lc_str_ = &value;
  }
  FmtElm(Object* value) : type_(OBJ) {  // NOLINT
    data_.u_obj_ = value;
  }
  FmtElm(Handle<Object> value) : type_(HANDLE) {  // NOLINT
    data_.u_handle_ = value.location();
  }
  FmtElm(void* value) : type_(POINTER) {  // NOLINT
    data_.u_pointer_ = value;
  }

 private:
  friend class StringStream;
  enum Type { INT, DOUBLE, C_STR, LC_STR, OBJ, HANDLE, POINTER };
  Type type_;
  union {
    int u_int_;
    double u_double_;
    const char* u_c_str_;
    const Vector<const uc16>* u_lc_str_;
    Object* u_obj_;
    Object** u_handle_;
    void* u_pointer_;
  } data_;
};


class StringStream final {
 public:
  enum ObjectPrintMode { kPrintObjectConcise, kPrintObjectVerbose };
  StringStream(StringAllocator* allocator,
               ObjectPrintMode object_print_mode = kPrintObjectVerbose)
      : allocator_(allocator),
        object_print_mode_(object_print_mode),
        capacity_(kInitialCapacity),
        length_(0),
        buffer_(allocator_->allocate(kInitialCapacity)) {
    buffer_[0] = 0;
  }

  bool Put(char c);
  bool Put(String* str);
  bool Put(String* str, int start, int end);
  void Add(Vector<const char> format, Vector<FmtElm> elms);
  void Add(const char* format);
  void Add(Vector<const char> format);
  void Add(const char* format, FmtElm arg0);
  void Add(const char* format, FmtElm arg0, FmtElm arg1);
  void Add(const char* format, FmtElm arg0, FmtElm arg1, FmtElm arg2);
  void Add(const char* format,
           FmtElm arg0,
           FmtElm arg1,
           FmtElm arg2,
           FmtElm arg3);
  void Add(const char* format,
           FmtElm arg0,
           FmtElm arg1,
           FmtElm arg2,
           FmtElm arg3,
           FmtElm arg4);

  // Getting the message out.
  void OutputToFile(FILE* out);
  void OutputToStdOut() { OutputToFile(stdout); }
  void Log(Isolate* isolate);
  Handle<String> ToString(Isolate* isolate);
  std::unique_ptr<char[]> ToCString() const;
  int length() const { return length_; }

  // Object printing support.
  void PrintName(Object* o);
  void PrintFixedArray(FixedArray* array, unsigned int limit);
  void PrintByteArray(ByteArray* ba);
  void PrintUsingMap(JSObject* js_object);
  void PrintPrototype(JSFunction* fun, Object* receiver);
  void PrintSecurityTokenIfChanged(Object* function);
  // NOTE: Returns the code in the output parameter.
  void PrintFunction(Object* function, Object* receiver, Code** code);

  // Reset the stream.
  void Reset() {
    length_ = 0;
    buffer_[0] = 0;
  }

  // Mentioned object cache support.
  void PrintMentionedObjectCache(Isolate* isolate);
  static void ClearMentionedObjectCache(Isolate* isolate);
#ifdef DEBUG
  bool IsMentionedObjectCacheClear(Isolate* isolate);
#endif

  static const int kInitialCapacity = 16;

 private:
  void PrintObject(Object* obj);

  StringAllocator* allocator_;
  ObjectPrintMode object_print_mode_;
  unsigned capacity_;
  unsigned length_;  // does not include terminating 0-character
  char* buffer_;

  bool full() const { return (capacity_ - length_) == 1; }
  int space() const { return capacity_ - length_; }

  DISALLOW_IMPLICIT_CONSTRUCTORS(StringStream);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_STRING_STREAM_H_
