// Copyright 2016 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/inspector/string-util.h"

#include <cinttypes>
#include <cmath>

#include "src/base/platform/platform.h"
#include "src/inspector/protocol/Protocol.h"
#include "src/numbers/conversions.h"

namespace v8_inspector {

v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string) {
  if (string.isEmpty()) return v8::String::Empty(isolate);
  DCHECK_GT(v8::String::kMaxLength, string.length());
  return v8::String::NewFromTwoByte(
             isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
             v8::NewStringType::kNormal, static_cast<int>(string.length()))
      .ToLocalChecked();
}

v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
                                             const String16& string) {
  if (string.isEmpty()) return v8::String::Empty(isolate);
  DCHECK_GT(v8::String::kMaxLength, string.length());
  return v8::String::NewFromTwoByte(
             isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
             v8::NewStringType::kInternalized,
             static_cast<int>(string.length()))
      .ToLocalChecked();
}

v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
                                             const char* str) {
  return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized)
      .ToLocalChecked();
}

v8::Local<v8::String> toV8String(v8::Isolate* isolate,
                                 const StringView& string) {
  if (!string.length()) return v8::String::Empty(isolate);
  DCHECK_GT(v8::String::kMaxLength, string.length());
  if (string.is8Bit())
    return v8::String::NewFromOneByte(
               isolate, reinterpret_cast<const uint8_t*>(string.characters8()),
               v8::NewStringType::kNormal, static_cast<int>(string.length()))
        .ToLocalChecked();
  return v8::String::NewFromTwoByte(
             isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
             v8::NewStringType::kNormal, static_cast<int>(string.length()))
      .ToLocalChecked();
}

String16 toProtocolString(v8::Isolate* isolate, v8::Local<v8::String> value) {
  if (value.IsEmpty() || value->IsNullOrUndefined()) return String16();
  std::unique_ptr<UChar[]> buffer(new UChar[value->Length()]);
  value->Write(isolate, reinterpret_cast<uint16_t*>(buffer.get()), 0,
               value->Length());
  return String16(buffer.get(), value->Length());
}

String16 toProtocolStringWithTypeCheck(v8::Isolate* isolate,
                                       v8::Local<v8::Value> value) {
  if (value.IsEmpty() || !value->IsString()) return String16();
  return toProtocolString(isolate, value.As<v8::String>());
}

String16 toString16(const StringView& string) {
  if (!string.length()) return String16();
  if (string.is8Bit())
    return String16(reinterpret_cast<const char*>(string.characters8()),
                    string.length());
  return String16(reinterpret_cast<const UChar*>(string.characters16()),
                  string.length());
}

StringView toStringView(const String16& string) {
  if (string.isEmpty()) return StringView();
  return StringView(reinterpret_cast<const uint16_t*>(string.characters16()),
                    string.length());
}

bool stringViewStartsWith(const StringView& string, const char* prefix) {
  if (!string.length()) return !(*prefix);
  if (string.is8Bit()) {
    for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
      if (string.characters8()[i] != prefix[j]) return false;
    }
  } else {
    for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
      if (string.characters16()[i] != prefix[j]) return false;
    }
  }
  return true;
}

namespace protocol {

// static
double StringUtil::toDouble(const char* s, size_t len, bool* isOk) {
  int flags = v8::internal::ALLOW_HEX | v8::internal::ALLOW_OCTAL |
              v8::internal::ALLOW_BINARY;
  double result = v8::internal::StringToDouble(s, flags);
  *isOk = !std::isnan(result);
  return result;
}

std::unique_ptr<protocol::Value> StringUtil::parseJSON(
    const StringView& string) {
  if (!string.length()) return nullptr;
  if (string.is8Bit()) {
    return parseJSONCharacters(string.characters8(),
                               static_cast<int>(string.length()));
  }
  return parseJSONCharacters(string.characters16(),
                             static_cast<int>(string.length()));
}

std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) {
  if (!string.length()) return nullptr;
  return parseJSONCharacters(string.characters16(),
                             static_cast<int>(string.length()));
}

// static
ProtocolMessage StringUtil::jsonToMessage(String message) {
  ProtocolMessage result;
  result.json = std::move(message);
  return result;
}

// static
ProtocolMessage StringUtil::binaryToMessage(std::vector<uint8_t> message) {
  ProtocolMessage result;
  result.binary = std::move(message);
  return result;
}

// static
void StringUtil::builderAppendQuotedString(StringBuilder& builder,
                                           const String& str) {
  builder.append('"');
  if (!str.isEmpty()) {
    escapeWideStringForJSON(
        reinterpret_cast<const uint16_t*>(str.characters16()),
        static_cast<int>(str.length()), &builder);
  }
  builder.append('"');
}

}  // namespace protocol

// static
std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) {
  String16 owner = toString16(string);
  return StringBufferImpl::adopt(owner);
}

// static
std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) {
  return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(string));
}

StringBufferImpl::StringBufferImpl(String16& string) {
  m_owner.swap(string);
  m_string = toStringView(m_owner);
}

String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId) {
  const size_t kBufferSize = 35;

  char buffer[kBufferSize];
  v8::base::OS::SNPrintF(buffer, kBufferSize, "(%08" PRIX64 "%08" PRIX64 ")",
                         debuggerId.first, debuggerId.second);
  return String16(buffer);
}

String16 stackTraceIdToString(uintptr_t id) {
  String16Builder builder;
  builder.appendNumber(static_cast<size_t>(id));
  return builder.toString();
}

}  // namespace v8_inspector
