// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/assert.h"

#include "platform/unicode.h"
#include "vm/double_conversion.h"
#include "vm/json_writer.h"
#include "vm/object.h"

namespace dart {

class MaybeOnStackBuffer {
 public:
  explicit MaybeOnStackBuffer(intptr_t size) {
    if (size > kOnStackBufferCapacity) {
      p_ = reinterpret_cast<char*>(malloc(size));
    } else {
      p_ = &buffer_[0];
    }
  }
  ~MaybeOnStackBuffer() {
    if (p_ != &buffer_[0]) free(p_);
  }

  char* p() { return p_; }

 private:
  static constexpr intptr_t kOnStackBufferCapacity = 4096;
  char* p_;
  char buffer_[kOnStackBufferCapacity];
};

JSONWriter::JSONWriter(intptr_t buf_size)
    : open_objects_(0), buffer_(buf_size) {}

void JSONWriter::AppendBytes(const uint8_t* buffer, intptr_t buffer_length) {
  buffer_.AddRaw(buffer, buffer_length);
}

static const char base64_digits[65] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64_pad = '=';

void JSONWriter::AppendBytesInBase64(const uint8_t* bytes, intptr_t length) {
  ASSERT(bytes != nullptr);
  intptr_t odd_bits = length % 3;
  intptr_t even_bits = length - odd_bits;
  for (intptr_t i = 0; i < even_bits; i += 3) {
    intptr_t triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
    buffer_.AddChar(base64_digits[triplet >> 18]);
    buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
    buffer_.AddChar(base64_digits[(triplet >> 6) & 63]);
    buffer_.AddChar(base64_digits[triplet & 63]);
  }
  if (odd_bits == 1) {
    intptr_t triplet = bytes[even_bits] << 16;
    buffer_.AddChar(base64_digits[triplet >> 18]);
    buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
    buffer_.AddChar(base64_pad);
    buffer_.AddChar(base64_pad);
  } else if (odd_bits == 2) {
    intptr_t triplet = (bytes[even_bits] << 16) | (bytes[even_bits + 1] << 8);
    buffer_.AddChar(base64_digits[triplet >> 18]);
    buffer_.AddChar(base64_digits[(triplet >> 12) & 63]);
    buffer_.AddChar(base64_digits[(triplet >> 6) & 63]);
    buffer_.AddChar(base64_pad);
  }
}

void JSONWriter::AppendSerializedObject(const char* serialized_object) {
  PrintCommaIfNeeded();
  buffer_.AddString(serialized_object);
}

void JSONWriter::AppendSerializedObject(const char* property_name,
                                        const char* serialized_object) {
  PrintCommaIfNeeded();
  PrintPropertyName(property_name);
  buffer_.AddString(serialized_object);
}

void JSONWriter::Clear() {
  buffer_.Clear();
  open_objects_ = 0;
}

void JSONWriter::OpenObject(const char* property_name) {
  PrintCommaIfNeeded();
  open_objects_++;
  if (property_name != nullptr) {
    PrintPropertyName(property_name);
  }
  buffer_.AddChar('{');
}

void JSONWriter::UncloseObject() {
  intptr_t len = buffer_.length();
  ASSERT(len > 0);
  ASSERT(buffer_.buffer()[len - 1] == '}');
  open_objects_++;
  buffer_.set_length(len - 1);
}

void JSONWriter::CloseObject() {
  ASSERT(open_objects_ > 0);
  open_objects_--;
  buffer_.AddChar('}');
}

void JSONWriter::OpenArray(const char* property_name) {
  PrintCommaIfNeeded();
  if (property_name != nullptr) {
    PrintPropertyName(property_name);
  }
  open_objects_++;
  buffer_.AddChar('[');
}

void JSONWriter::CloseArray() {
  ASSERT(open_objects_ > 0);
  open_objects_--;
  buffer_.AddChar(']');
}

void JSONWriter::PrintValueNull() {
  PrintCommaIfNeeded();
  buffer_.Printf("null");
}

void JSONWriter::PrintValueBool(bool b) {
  PrintCommaIfNeeded();
  buffer_.Printf("%s", b ? "true" : "false");
}

void JSONWriter::PrintValue(intptr_t i) {
  EnsureIntegerIsRepresentableInJavaScript(static_cast<int64_t>(i));
  PrintCommaIfNeeded();
  buffer_.Printf("%" Pd "", i);
}

void JSONWriter::PrintValue64(int64_t i) {
  EnsureIntegerIsRepresentableInJavaScript(i);
  PrintCommaIfNeeded();
  buffer_.Printf("%" Pd64 "", i);
}

void JSONWriter::PrintValue(double d) {
  // Max length of a double in characters (including \0).
  // See double_conversion.cc.
  const size_t kBufferLen = 25;
  char buffer[kBufferLen];
  DoubleToCString(d, buffer, kBufferLen);
  PrintCommaIfNeeded();
  buffer_.Printf("%s", buffer);
}

void JSONWriter::PrintValueBase64(const uint8_t* bytes, intptr_t length) {
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  AppendBytesInBase64(bytes, length);
  buffer_.AddChar('"');
}

void JSONWriter::PrintValue(const char* s) {
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  AddEscapedUTF8String(s);
  buffer_.AddChar('"');
}

void JSONWriter::PrintValue(const char* s, intptr_t i) {
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  AddEscapedUTF8String(s, i);
  buffer_.AddChar('"');
}

bool JSONWriter::PrintValueStr(const String& s,
                               intptr_t offset,
                               intptr_t count) {
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  bool did_truncate = AddDartString(s, offset, count);
  buffer_.AddChar('"');
  return did_truncate;
}

void JSONWriter::PrintValueNoEscape(const char* s) {
  PrintCommaIfNeeded();
  buffer_.Printf("%s", s);
}

void JSONWriter::PrintfValue(const char* format, ...) {
  va_list args;
  va_start(args, format);
  VPrintfValue(format, args);
  va_end(args);
}

void JSONWriter::VPrintfValue(const char* format, va_list args) {
  PrintCommaIfNeeded();

  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
  va_end(measure_args);

  MaybeOnStackBuffer mosb(len + 1);
  char* p = mosb.p();

  va_list print_args;
  va_copy(print_args, args);
  intptr_t len2 = Utils::VSNPrint(p, len + 1, format, print_args);
  va_end(print_args);
  ASSERT(len == len2);

  buffer_.AddChar('"');
  AddEscapedUTF8String(p, len);
  buffer_.AddChar('"');
}

void JSONWriter::PrintPropertyBool(const char* name, bool b) {
  PrintPropertyName(name);
  PrintValueBool(b);
}

void JSONWriter::PrintProperty(const char* name, intptr_t i) {
  PrintPropertyName(name);
  PrintValue(i);
}

void JSONWriter::PrintProperty64(const char* name, int64_t i) {
  PrintPropertyName(name);
  PrintValue64(i);
}

void JSONWriter::PrintProperty(const char* name, double d) {
  PrintPropertyName(name);
  PrintValue(d);
}

void JSONWriter::PrintProperty(const char* name, const char* s) {
  PrintPropertyName(name);
  PrintValue(s);
}

void JSONWriter::PrintPropertyBase64(const char* name,
                                     const uint8_t* b,
                                     intptr_t len) {
  PrintPropertyName(name);
  PrintValueBase64(b, len);
}

bool JSONWriter::PrintPropertyStr(const char* name,
                                  const String& s,
                                  intptr_t offset,
                                  intptr_t count) {
  PrintPropertyName(name);
  return PrintValueStr(s, offset, count);
}

void JSONWriter::PrintPropertyNoEscape(const char* name, const char* s) {
  PrintPropertyName(name);
  PrintValueNoEscape(s);
}

void JSONWriter::PrintfProperty(const char* name, const char* format, ...) {
  va_list args;
  va_start(args, format);
  VPrintfProperty(name, format, args);
  va_end(args);
}

void JSONWriter::VPrintfProperty(const char* name,
                                 const char* format,
                                 va_list args) {
  PrintPropertyName(name);

  va_list measure_args;
  va_copy(measure_args, args);
  intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
  va_end(measure_args);

  MaybeOnStackBuffer mosb(len + 1);
  char* p = mosb.p();

  va_list print_args;
  va_copy(print_args, args);
  intptr_t len2 = Utils::VSNPrint(p, len + 1, format, print_args);
  va_end(print_args);
  ASSERT(len == len2);

  buffer_.AddChar('"');
  AddEscapedUTF8String(p, len);
  buffer_.AddChar('"');
}

void JSONWriter::Steal(char** buffer, intptr_t* buffer_length) {
  ASSERT(buffer != nullptr);
  ASSERT(buffer_length != nullptr);
  *buffer_length = buffer_.length();
  *buffer = buffer_.Steal();
}

void JSONWriter::PrintPropertyName(const char* name) {
  ASSERT(name != nullptr);
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  AddEscapedUTF8String(name);
  buffer_.AddChar('"');
  buffer_.AddChar(':');
}

void JSONWriter::PrintNewline() {
  buffer_.AddChar('\n');
}

void JSONWriter::PrintCommaIfNeeded() {
  if (NeedComma()) {
    buffer_.AddChar(',');
  }
}

bool JSONWriter::NeedComma() {
  const char* buffer = buffer_.buffer();
  intptr_t length = buffer_.length();
  if (length == 0) {
    return false;
  }
  char ch = buffer[length - 1];
  return (ch != '[') && (ch != '{') && (ch != ':') && (ch != ',');
}

void JSONWriter::EnsureIntegerIsRepresentableInJavaScript(int64_t i) {
#ifdef DEBUG
  if (!Utils::IsJavaScriptInt(i)) {
    OS::PrintErr(
        "JSONWriter::EnsureIntegerIsRepresentableInJavaScript failed on "
        "%" Pd64 "\n",
        i);
    UNREACHABLE();
  }
#endif
}

void JSONWriter::AddEscapedUTF8String(const char* s) {
  if (s == nullptr) {
    return;
  }
  intptr_t len = strlen(s);
  AddEscapedUTF8String(s, len);
}

void JSONWriter::AddEscapedUTF8String(const char* s, intptr_t len) {
  if (s == nullptr) {
    return;
  }
  buffer_.AddEscapedUTF8(s, len);
}

bool JSONWriter::AddDartString(const String& s,
                               intptr_t offset,
                               intptr_t count) {
  intptr_t length = s.Length();
  ASSERT(offset >= 0);
  if (offset > length) {
    offset = length;
  }
  if (!Utils::RangeCheck(offset, count, length)) {
    count = length - offset;
  }

  if (count > 0) {  // Avoid asserts about harmless out-of-bounds index.
    NoSafepointScope no_safepoint;
    if (s.IsOneByteString()) {
      buffer_.AddEscapedLatin1(OneByteString::CharAddr(s, offset), count);
    } else if (s.IsExternalOneByteString()) {
      buffer_.AddEscapedLatin1(ExternalOneByteString::CharAddr(s, offset),
                               count);
    } else if (s.IsTwoByteString()) {
      buffer_.AddEscapedUTF16(TwoByteString::CharAddr(s, offset), count);
    } else if (s.IsExternalTwoByteString()) {
      buffer_.AddEscapedUTF16(ExternalTwoByteString::CharAddr(s, offset),
                              count);
    } else {
      UNREACHABLE();
    }
  }

  // Return value indicates whether the string is truncated.
  intptr_t limit = offset + count;
  return (offset > 0) || (limit < length);
}

}  // namespace dart
