// Copyright 2015 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/profiler/strings-storage.h"

#include <memory>

#include "src/utils/allocation.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

bool StringsStorage::StringsMatch(void* key1, void* key2) {
  return strcmp(reinterpret_cast<char*>(key1), reinterpret_cast<char*>(key2)) ==
         0;
}

StringsStorage::StringsStorage() : names_(StringsMatch) {}

StringsStorage::~StringsStorage() {
  for (base::HashMap::Entry* p = names_.Start(); p != nullptr;
       p = names_.Next(p)) {
    DeleteArray(reinterpret_cast<const char*>(p->value));
  }
}

const char* StringsStorage::GetCopy(const char* src) {
  int len = static_cast<int>(strlen(src));
  base::HashMap::Entry* entry = GetEntry(src, len);
  if (entry->value == nullptr) {
    Vector<char> dst = Vector<char>::New(len + 1);
    StrNCpy(dst, src, len);
    dst[len] = '\0';
    entry->key = dst.begin();
    entry->value = entry->key;
  }
  return reinterpret_cast<const char*>(entry->value);
}

const char* StringsStorage::GetFormatted(const char* format, ...) {
  va_list args;
  va_start(args, format);
  const char* result = GetVFormatted(format, args);
  va_end(args);
  return result;
}

const char* StringsStorage::AddOrDisposeString(char* str, int len) {
  base::HashMap::Entry* entry = GetEntry(str, len);
  if (entry->value == nullptr) {
    // New entry added.
    entry->key = str;
    entry->value = str;
  } else {
    DeleteArray(str);
  }
  return reinterpret_cast<const char*>(entry->value);
}

const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
  Vector<char> str = Vector<char>::New(1024);
  int len = VSNPrintF(str, format, args);
  if (len == -1) {
    DeleteArray(str.begin());
    return GetCopy(format);
  }
  return AddOrDisposeString(str.begin(), len);
}

const char* StringsStorage::GetName(Name name) {
  if (name.IsString()) {
    String str = String::cast(name);
    int length = Min(FLAG_heap_snapshot_string_limit, str.length());
    int actual_length = 0;
    std::unique_ptr<char[]> data = str.ToCString(
        DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);
    return AddOrDisposeString(data.release(), actual_length);
  } else if (name.IsSymbol()) {
    return "<symbol>";
  }
  return "";
}

const char* StringsStorage::GetName(int index) {
  return GetFormatted("%d", index);
}

const char* StringsStorage::GetConsName(const char* prefix, Name name) {
  if (name.IsString()) {
    String str = String::cast(name);
    int length = Min(FLAG_heap_snapshot_string_limit, str.length());
    int actual_length = 0;
    std::unique_ptr<char[]> data = str.ToCString(
        DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length, &actual_length);

    int cons_length = actual_length + static_cast<int>(strlen(prefix)) + 1;
    char* cons_result = NewArray<char>(cons_length);
    snprintf(cons_result, cons_length, "%s%s", prefix, data.get());

    return AddOrDisposeString(cons_result, cons_length);
  } else if (name.IsSymbol()) {
    return "<symbol>";
  }
  return "";
}

base::HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) {
  uint32_t hash = StringHasher::HashSequentialString(str, len, kZeroHashSeed);
  return names_.LookupOrInsert(const_cast<char*>(str), hash);
}

}  // namespace internal
}  // namespace v8
