// Copyright 2018 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"

#if !V8_OS_STARBOARD
#include <cstdio>
#endif

#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace v8 {
namespace internal {

using StringsStorageWithIsolate = TestWithIsolate;

bool StringEq(const char* left, const char* right) {
  return strcmp(left, right) == 0;
}

TEST_F(StringsStorageWithIsolate, GetNameFromString) {
  StringsStorage storage;

  // One char strings are canonical on the v8 heap so use a 2 char string here.
  Handle<String> str = isolate()->factory()->NewStringFromAsciiChecked("xy");
  const char* stored_str = storage.GetName(*str);
  CHECK(StringEq("xy", stored_str));

  // The storage should de-duplicate the underlying char arrays and return the
  // exact same pointer for equivalent input strings.
  const char* stored_str_twice = storage.GetName(*str);
  CHECK_EQ(stored_str, stored_str_twice);

  // Even if the input string was a different one on the v8 heap, if the char
  // array is the same, it should be de-duplicated.
  Handle<String> str2 = isolate()->factory()->NewStringFromAsciiChecked("xy");
  CHECK_NE(*str, *str2);
  const char* stored_str_thrice = storage.GetName(*str2);
  CHECK_EQ(stored_str_twice, stored_str_thrice);
}

TEST_F(StringsStorageWithIsolate, GetNameFromSymbol) {
  StringsStorage storage;

  Handle<Symbol> symbol = isolate()->factory()->NewSymbol();
  const char* stored_symbol = storage.GetName(*symbol);
  CHECK(StringEq("<symbol>", stored_symbol));

  Handle<Symbol> symbol2 = isolate()->factory()->NewSymbol();
  CHECK_NE(*symbol, *symbol2);
  const char* stored_symbol2 = storage.GetName(*symbol2);
  CHECK_EQ(stored_symbol, stored_symbol2);
}

TEST_F(StringsStorageWithIsolate, GetConsName) {
  StringsStorage storage;

  Handle<String> str = isolate()->factory()->NewStringFromAsciiChecked("xy");

  const char* empty_prefix_str = storage.GetConsName("", *str);
  CHECK(StringEq("xy", empty_prefix_str));

  const char* get_str = storage.GetConsName("get ", *str);
  CHECK(StringEq("get xy", get_str));
}

TEST_F(StringsStorageWithIsolate, GetNameFromInt) {
  StringsStorage storage;

  const char* stored_str = storage.GetName(0);
  CHECK(StringEq("0", stored_str));

  stored_str = storage.GetName(2147483647);
  CHECK(StringEq("2147483647", stored_str));

  stored_str = storage.GetName(std::numeric_limits<int>::min());
  char str_negative_int[12];
  snprintf(str_negative_int, sizeof(str_negative_int), "%d",
           std::numeric_limits<int>::min());
  CHECK(StringEq(str_negative_int, stored_str));
}

TEST_F(StringsStorageWithIsolate, Format) {
  StringsStorage storage;

  const char* xy = "xy";
  const char* stored_str = storage.GetFormatted("%s", xy);
  CHECK(StringEq("xy", stored_str));
  // Check that the string is copied.
  CHECK_NE(xy, stored_str);

  const char* formatted_str = storage.GetFormatted("%s / %s", xy, xy);
  CHECK(StringEq("xy / xy", formatted_str));

  // A different format specifier that results in the same string should share
  // the string in storage.
  const char* formatted_str2 = storage.GetFormatted("%s", "xy / xy");
  CHECK_EQ(formatted_str, formatted_str2);
}

TEST_F(StringsStorageWithIsolate, FormatAndGetShareStorage) {
  StringsStorage storage;

  Handle<String> str = isolate()->factory()->NewStringFromAsciiChecked("xy");
  const char* stored_str = storage.GetName(*str);

  const char* formatted_str = storage.GetFormatted("%s", "xy");
  CHECK_EQ(stored_str, formatted_str);
}

}  // namespace internal
}  // namespace v8
