// Copyright 2020 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 <cmath>
#include <iostream>
#include <limits>
#include <memory>

#include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/handles/handles-inl.h"
#include "src/handles/handles.h"
#include "src/handles/maybe-handles.h"
#include "src/heap/local-factory-inl.h"
#include "src/objects/fixed-array.h"
#include "src/objects/script.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/string.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser.h"
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/scanner.h"
#include "src/strings/unicode-inl.h"
#include "src/utils/utils.h"
#include "test/unittests/test-utils.h"

namespace v8 {
namespace internal {

class LocalIsolate;

namespace {

std::vector<uint16_t> DecodeUtf8(const std::string& string) {
  if (string.empty()) return {};

  auto utf8_data =
      Vector<const uint8_t>::cast(VectorOf(string.data(), string.length()));
  Utf8Decoder decoder(utf8_data);

  std::vector<uint16_t> utf16(decoder.utf16_length());
  decoder.Decode(&utf16[0], utf8_data);

  return utf16;
}

}  // namespace

class LocalFactoryTest : public TestWithIsolateAndZone {
 public:
  LocalFactoryTest()
      : TestWithIsolateAndZone(),
        state_(isolate()),
        parse_info_(
            isolate(),
            UnoptimizedCompileFlags::ForToplevelCompile(
                isolate(), true, construct_language_mode(FLAG_use_strict),
                REPLMode::kNo),
            &state_),
        local_isolate_(isolate(), ThreadKind::kMain),
        unparked_scope_(local_isolate_.heap()) {
    FLAG_concurrent_allocation = true;
  }

  FunctionLiteral* ParseProgram(const char* source) {
    auto utf16_source = DecodeUtf8(source);

    // Normally this would be an external string or whatever, we don't have to
    // worry about it for now.
    source_string_ =
        factory()->NewStringFromUtf8(CStrVector(source)).ToHandleChecked();

    parse_info_.set_character_stream(
        ScannerStream::ForTesting(utf16_source.data(), utf16_source.size()));

    {
      DisallowHeapAllocation no_allocation;
      DisallowHandleAllocation no_handles;
      DisallowHeapAccess no_heap_access;

      Parser parser(parse_info());
      parser.InitializeEmptyScopeChain(parse_info());
      parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel);
    }

    parse_info()->ast_value_factory()->Internalize(local_isolate());
    DeclarationScope::AllocateScopeInfos(parse_info(), local_isolate());

    script_ = parse_info_.CreateScript(local_isolate(),
                                       local_factory()->empty_string(),
                                       kNullMaybeHandle, ScriptOriginOptions());

    // Create the SFI list on the script so that SFI SetScript works.
    Handle<WeakFixedArray> infos = local_factory()->NewWeakFixedArray(
        parse_info()->max_function_literal_id() + 1, AllocationType::kOld);
    script_->set_shared_function_infos(*infos);

    return parse_info()->literal();
  }

  ParseInfo* parse_info() { return &parse_info_; }

  Handle<Script> script() { return script_; }

  LocalIsolate* local_isolate() { return &local_isolate_; }
  LocalFactory* local_factory() { return local_isolate()->factory(); }

 private:
  SaveFlags save_flags_;
  UnoptimizedCompileState state_;
  ParseInfo parse_info_;
  LocalIsolate local_isolate_;
  UnparkedScope unparked_scope_;
  Handle<String> source_string_;
  Handle<Script> script_;
};

TEST_F(LocalFactoryTest, OneByteInternalizedString_IsAddedToStringTable) {
  Vector<const uint8_t> string_vector = StaticOneByteVector("foo");

  Handle<String> string;
  {
    LocalHandleScope handle_scope(local_isolate());

    Handle<String> local_string =
        local_factory()->InternalizeString(string_vector);

    string = local_isolate()->heap()->NewPersistentHandle(local_string);
  }

  EXPECT_TRUE(string->IsOneByteEqualTo(CStrVector("foo")));
  EXPECT_TRUE(string->IsInternalizedString());

  Handle<String> same_string = isolate()
                                   ->factory()
                                   ->NewStringFromOneByte(string_vector)
                                   .ToHandleChecked();
  EXPECT_NE(*string, *same_string);
  EXPECT_FALSE(same_string->IsInternalizedString());

  Handle<String> internalized_string =
      isolate()->factory()->InternalizeString(same_string);
  EXPECT_EQ(*string, *internalized_string);
}

TEST_F(LocalFactoryTest, OneByteInternalizedString_DuplicateIsDeduplicated) {
  Vector<const uint8_t> string_vector = StaticOneByteVector("foo");

  Handle<String> string_1;
  Handle<String> string_2;
  {
    LocalHandleScope handle_scope(local_isolate());

    Handle<String> local_string_1 =
        local_factory()->InternalizeString(string_vector);
    Handle<String> local_string_2 =
        local_factory()->InternalizeString(string_vector);

    string_1 = local_isolate()->heap()->NewPersistentHandle(local_string_1);
    string_2 = local_isolate()->heap()->NewPersistentHandle(local_string_2);
  }

  EXPECT_TRUE(string_1->IsOneByteEqualTo(CStrVector("foo")));
  EXPECT_TRUE(string_1->IsInternalizedString());
  EXPECT_EQ(*string_1, *string_2);
}

TEST_F(LocalFactoryTest, AstRawString_IsInternalized) {
  AstValueFactory ast_value_factory(zone(), isolate()->ast_string_constants(),
                                    HashSeed(isolate()));

  const AstRawString* raw_string = ast_value_factory.GetOneByteString("foo");

  Handle<String> string;
  {
    LocalHandleScope handle_scope(local_isolate());

    ast_value_factory.Internalize(local_isolate());

    string = local_isolate()->heap()->NewPersistentHandle(raw_string->string());
  }

  EXPECT_TRUE(string->IsOneByteEqualTo(CStrVector("foo")));
  EXPECT_TRUE(string->IsInternalizedString());
}

TEST_F(LocalFactoryTest, AstConsString_CreatesConsString) {
  AstValueFactory ast_value_factory(zone(), isolate()->ast_string_constants(),
                                    HashSeed(isolate()));

  Handle<String> string;
  {
    LocalHandleScope handle_scope(local_isolate());

    const AstRawString* foo_string = ast_value_factory.GetOneByteString("foo");
    const AstRawString* bar_string =
        ast_value_factory.GetOneByteString("bar-plus-padding-for-length");
    AstConsString* foobar_string =
        ast_value_factory.NewConsString(foo_string, bar_string);

    ast_value_factory.Internalize(local_isolate());

    string = local_isolate()->heap()->NewPersistentHandle(
        foobar_string->GetString(local_isolate()));
  }

  EXPECT_TRUE(string->IsConsString());
  EXPECT_TRUE(string->Equals(*isolate()->factory()->NewStringFromStaticChars(
      "foobar-plus-padding-for-length")));
}

TEST_F(LocalFactoryTest, EmptyScript) {
  FunctionLiteral* program = ParseProgram("");

  Handle<SharedFunctionInfo> shared;
  {
    LocalHandleScope handle_scope(local_isolate());

    shared = local_isolate()->heap()->NewPersistentHandle(
        local_factory()->NewSharedFunctionInfoForLiteral(program, script(),
                                                         true));
  }
  Handle<SharedFunctionInfo> root_sfi = shared;

  EXPECT_EQ(root_sfi->function_literal_id(), 0);
}

TEST_F(LocalFactoryTest, LazyFunction) {
  FunctionLiteral* program = ParseProgram("function lazy() {}");
  FunctionLiteral* lazy = program->scope()
                              ->declarations()
                              ->AtForTest(0)
                              ->AsFunctionDeclaration()
                              ->fun();

  Handle<SharedFunctionInfo> shared;
  {
    LocalHandleScope handle_scope(local_isolate());

    shared = local_isolate()->heap()->NewPersistentHandle(
        local_factory()->NewSharedFunctionInfoForLiteral(lazy, script(), true));
  }
  Handle<SharedFunctionInfo> lazy_sfi = shared;

  EXPECT_EQ(lazy_sfi->function_literal_id(), 1);
  EXPECT_TRUE(lazy_sfi->Name().IsOneByteEqualTo(CStrVector("lazy")));
  EXPECT_FALSE(lazy_sfi->is_compiled());
  EXPECT_TRUE(lazy_sfi->HasUncompiledDataWithoutPreparseData());
}

TEST_F(LocalFactoryTest, EagerFunction) {
  FunctionLiteral* program = ParseProgram("(function eager() {})");
  // Rewritten to `.result = (function eager() {}); return .result`
  FunctionLiteral* eager = program->body()
                               ->at(0)
                               ->AsExpressionStatement()
                               ->expression()
                               ->AsAssignment()
                               ->value()
                               ->AsFunctionLiteral();

  Handle<SharedFunctionInfo> shared;
  {
    LocalHandleScope handle_scope(local_isolate());

    shared = local_isolate()->heap()->NewPersistentHandle(
        local_factory()->NewSharedFunctionInfoForLiteral(eager, script(),
                                                         true));
  }
  Handle<SharedFunctionInfo> eager_sfi = shared;

  EXPECT_EQ(eager_sfi->function_literal_id(), 1);
  EXPECT_TRUE(eager_sfi->Name().IsOneByteEqualTo(CStrVector("eager")));
  EXPECT_FALSE(eager_sfi->HasUncompiledData());
  // TODO(leszeks): Add compilation support and enable these checks.
  // EXPECT_TRUE(eager_sfi->is_compiled());
  // EXPECT_TRUE(eager_sfi->HasBytecodeArray());
}

TEST_F(LocalFactoryTest, ImplicitNameFunction) {
  FunctionLiteral* program = ParseProgram("let implicit_name = function() {}");
  FunctionLiteral* implicit_name = program->body()
                                       ->at(0)
                                       ->AsBlock()
                                       ->statements()
                                       ->at(0)
                                       ->AsExpressionStatement()
                                       ->expression()
                                       ->AsAssignment()
                                       ->value()
                                       ->AsFunctionLiteral();

  Handle<SharedFunctionInfo> shared;
  {
    LocalHandleScope handle_scope(local_isolate());

    shared = local_isolate()->heap()->NewPersistentHandle(
        local_factory()->NewSharedFunctionInfoForLiteral(implicit_name,
                                                         script(), true));
  }
  Handle<SharedFunctionInfo> implicit_name_sfi = shared;

  EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
  EXPECT_TRUE(
      implicit_name_sfi->Name().IsOneByteEqualTo(CStrVector("implicit_name")));
}

TEST_F(LocalFactoryTest, GCDuringPublish) {
  FunctionLiteral* program = ParseProgram("let implicit_name = function() {}");
  FunctionLiteral* implicit_name = program->body()
                                       ->at(0)
                                       ->AsBlock()
                                       ->statements()
                                       ->at(0)
                                       ->AsExpressionStatement()
                                       ->expression()
                                       ->AsAssignment()
                                       ->value()
                                       ->AsFunctionLiteral();

  Handle<SharedFunctionInfo> shared;
  {
    LocalHandleScope handle_scope(local_isolate());

    shared = local_isolate()->heap()->NewPersistentHandle(
        local_factory()->NewSharedFunctionInfoForLiteral(implicit_name,
                                                         script(), true));
  }
  Handle<SharedFunctionInfo> implicit_name_sfi = shared;

  EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
  EXPECT_TRUE(
      implicit_name_sfi->Name().IsOneByteEqualTo(CStrVector("implicit_name")));
}

}  // namespace internal
}  // namespace v8
