// 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 <cstddef>

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

namespace v8_inspector {

namespace protocol {
namespace {
std::pair<uint8_t, uint8_t> SplitByte(uint8_t byte, uint8_t split) {
  return {byte >> split, (byte & ((1 << split) - 1)) << (6 - split)};
}

v8::Maybe<uint8_t> DecodeByte(char byte) {
  if ('A' <= byte && byte <= 'Z') return v8::Just<uint8_t>(byte - 'A');
  if ('a' <= byte && byte <= 'z') return v8::Just<uint8_t>(byte - 'a' + 26);
  if ('0' <= byte && byte <= '9')
    return v8::Just<uint8_t>(byte - '0' + 26 + 26);
  if (byte == '+') return v8::Just<uint8_t>(62);
  if (byte == '/') return v8::Just<uint8_t>(63);
  return v8::Nothing<uint8_t>();
}
}  // namespace

String Binary::toBase64() const {
  const char* table =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  if (size() == 0) return {};
  std::basic_string<UChar> result;
  result.reserve(4 * ((size() + 2) / 3));
  uint8_t last = 0;
  for (size_t n = 0; n < size();) {
    auto split = SplitByte((*bytes_)[n], 2 + 2 * (n % 3));
    result.push_back(table[split.first | last]);

    ++n;
    if (n < size() && n % 3 == 0) {
      result.push_back(table[split.second]);
      last = 0;
    } else {
      last = split.second;
    }
  }
  result.push_back(table[last]);
  while (result.size() % 4 > 0) result.push_back('=');
  return String16(std::move(result));
}

/* static */
Binary Binary::fromBase64(const String& base64, bool* success) {
  if (base64.isEmpty()) {
    *success = true;
    return Binary::fromSpan(nullptr, 0);
  }

  *success = false;
  // Fail if the length is invalid or decoding would overflow.
  if (base64.length() % 4 != 0 || base64.length() + 4 < base64.length()) {
    return Binary::fromSpan(nullptr, 0);
  }

  std::vector<uint8_t> result;
  result.reserve(3 * base64.length() / 4);
  char pad = '=';
  // Iterate groups of four
  for (size_t i = 0; i < base64.length(); i += 4) {
    uint8_t a = 0, b = 0, c = 0, d = 0;
    if (!DecodeByte(base64[i + 0]).To(&a)) return Binary::fromSpan(nullptr, 0);
    if (!DecodeByte(base64[i + 1]).To(&b)) return Binary::fromSpan(nullptr, 0);
    if (!DecodeByte(base64[i + 2]).To(&c)) {
      // Padding is allowed only in the group on the last two positions
      if (i + 4 < base64.length() || base64[i + 2] != pad ||
          base64[i + 3] != pad) {
        return Binary::fromSpan(nullptr, 0);
      }
    }
    if (!DecodeByte(base64[i + 3]).To(&d)) {
      // Padding is allowed only in the group on the last two positions
      if (i + 4 < base64.length() || base64[i + 3] != pad) {
        return Binary::fromSpan(nullptr, 0);
      }
    }

    result.push_back((a << 2) | (b >> 4));
    if (base64[i + 2] != '=') result.push_back((0xFF & (b << 4)) | (c >> 2));
    if (base64[i + 3] != '=') result.push_back((0xFF & (c << 6)) | d);
  }
  *success = true;
  return Binary(std::make_shared<std::vector<uint8_t>>(std::move(result)));
}
}  // namespace protocol

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(string.characters16(), string.length());
}

StringView toStringView(const String16& string) {
  if (string.isEmpty()) return StringView();
  return StringView(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 {
// An empty string buffer doesn't own any string data; its ::string() returns a
// default-constructed StringView instance.
class EmptyStringBuffer : public StringBuffer {
 public:
  StringView string() const override { return StringView(); }
};

// Contains LATIN1 text data or CBOR encoded binary data in a vector.
class StringBuffer8 : public StringBuffer {
 public:
  explicit StringBuffer8(std::vector<uint8_t> data) : data_(std::move(data)) {}

  StringView string() const override {
    return StringView(data_.data(), data_.size());
  }

 private:
  std::vector<uint8_t> data_;
};

// Contains a 16 bit string (String16).
class StringBuffer16 : public StringBuffer {
 public:
  explicit StringBuffer16(String16 data) : data_(std::move(data)) {}

  StringView string() const override {
    return StringView(data_.characters16(), data_.length());
  }

 private:
  String16 data_;
};
}  // namespace

// static
std::unique_ptr<StringBuffer> StringBuffer::create(StringView string) {
  if (string.length() == 0) return std::make_unique<EmptyStringBuffer>();
  if (string.is8Bit()) {
    return std::make_unique<StringBuffer8>(std::vector<uint8_t>(
        string.characters8(), string.characters8() + string.length()));
  }
  return std::make_unique<StringBuffer16>(
      String16(string.characters16(), string.length()));
}

std::unique_ptr<StringBuffer> StringBufferFrom(String16 str) {
  if (str.isEmpty()) return std::make_unique<EmptyStringBuffer>();
  return std::make_unique<StringBuffer16>(std::move(str));
}

std::unique_ptr<StringBuffer> StringBufferFrom(std::vector<uint8_t> str) {
  if (str.empty()) return std::make_unique<EmptyStringBuffer>();
  return std::make_unique<StringBuffer8>(std::move(str));
}

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

}  // namespace v8_inspector

namespace v8_crdtp {

using v8_inspector::String16;
using v8_inspector::protocol::Binary;
using v8_inspector::protocol::StringUtil;

// static
bool ProtocolTypeTraits<String16>::Deserialize(DeserializerState* state,
                                               String16* value) {
  auto* tokenizer = state->tokenizer();
  if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) {
    const auto str = tokenizer->GetString8();
    *value = StringUtil::fromUTF8(str.data(), str.size());
    return true;
  }
  if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) {
    const auto str = tokenizer->GetString16WireRep();
    *value = StringUtil::fromUTF16LE(
        reinterpret_cast<const uint16_t*>(str.data()), str.size() / 2);
    return true;
  }
  state->RegisterError(Error::BINDINGS_STRING_VALUE_EXPECTED);
  return false;
}

// static
void ProtocolTypeTraits<String16>::Serialize(const String16& value,
                                             std::vector<uint8_t>* bytes) {
  cbor::EncodeFromUTF16(
      span<uint16_t>(reinterpret_cast<const uint16_t*>(value.characters16()),
                     value.length()),
      bytes);
}

// static
bool ProtocolTypeTraits<Binary>::Deserialize(DeserializerState* state,
                                             Binary* value) {
  auto* tokenizer = state->tokenizer();
  if (tokenizer->TokenTag() == cbor::CBORTokenTag::BINARY) {
    const span<uint8_t> bin = tokenizer->GetBinary();
    *value = Binary::fromSpan(bin.data(), bin.size());
    return true;
  }
  if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) {
    const auto str_span = tokenizer->GetString8();
    auto str = StringUtil::fromUTF8(str_span.data(), str_span.size());
    bool success = false;
    *value = Binary::fromBase64(str, &success);
    return success;
  }
  state->RegisterError(Error::BINDINGS_BINARY_VALUE_EXPECTED);
  return false;
}

// static
void ProtocolTypeTraits<Binary>::Serialize(const Binary& value,
                                           std::vector<uint8_t>* bytes) {
  cbor::EncodeBinary(span<uint8_t>(value.data(), value.size()), bytes);
}

void SerializerTraits<Binary>::Serialize(
    const v8_inspector::protocol::Binary& binary, std::vector<uint8_t>* out) {
  cbor::EncodeBinary(span<uint8_t>(binary.data(), binary.size()), out);
}
}  // namespace v8_crdtp
