// 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 const intptr_t kOnStackBufferCapacity = 4096;
  char* p_;
  char buffer_[kOnStackBufferCapacity];
};

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

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

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

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 != NULL) {
    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 != NULL) {
    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);
}

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

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

  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);
  }

  buffer_.AddChar('"');
}

void JSONWriter::PrintValue(const char* s) {
  PrintCommaIfNeeded();
  buffer_.AddChar('"');
  AddEscapedUTF8String(s);
  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(NULL, 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(NULL, 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 != NULL);
  ASSERT(buffer_length != NULL);
  *buffer_length = buffer_.length();
  *buffer = buffer_.Steal();
}

void JSONWriter::PrintPropertyName(const char* name) {
  ASSERT(name != NULL);
  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 == NULL) {
    return;
  }
  intptr_t len = strlen(s);
  AddEscapedUTF8String(s, len);
}

void JSONWriter::AddEscapedUTF8String(const char* s, intptr_t len) {
  if (s == NULL) {
    return;
  }
  const uint8_t* s8 = reinterpret_cast<const uint8_t*>(s);
  intptr_t i = 0;
  for (; i < len;) {
    // Extract next UTF8 character.
    int32_t ch = 0;
    int32_t ch_len = Utf8::Decode(&s8[i], len - i, &ch);
    ASSERT(ch_len != 0);
    buffer_.EscapeAndAddCodeUnit(ch);
    // Move i forward.
    i += ch_len;
  }
  ASSERT(i == 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;
  }
  intptr_t limit = offset + count;
  for (intptr_t i = offset; i < limit; i++) {
    uint16_t code_unit = s.CharAt(i);
    if (Utf16::IsTrailSurrogate(code_unit)) {
      buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
    } else if (Utf16::IsLeadSurrogate(code_unit)) {
      if (i + 1 == limit) {
        buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
      } else {
        uint16_t next_code_unit = s.CharAt(i + 1);
        if (Utf16::IsTrailSurrogate(next_code_unit)) {
          uint32_t decoded = Utf16::Decode(code_unit, next_code_unit);
          buffer_.EscapeAndAddCodeUnit(decoded);
          i++;
        } else {
          buffer_.EscapeAndAddUTF16CodeUnit(code_unit);
        }
      }
    } else {
      buffer_.EscapeAndAddCodeUnit(code_unit);
    }
  }
  // Return value indicates whether the string is truncated.
  return (offset > 0) || (limit < length);
}

}  // namespace dart
