// Copyright 2017 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 "testing/gtest/include/gtest/gtest.h"

#include "include/libplatform/libplatform.h"
#include "include/v8-platform.h"
#include "include/v8.h"
#include "src/base/macros.h"
#include "src/base/platform/semaphore.h"
#include "src/execution/execution.h"
#include "src/execution/isolate.h"
#include "src/init/v8.h"
#include "test/unittests/test-utils.h"

namespace v8 {

using IsolateTest = TestWithIsolate;

namespace {

class MemoryPressureTask : public v8::Task {
 public:
  MemoryPressureTask(Isolate* isolate, base::Semaphore* semaphore)
      : isolate_(isolate), semaphore_(semaphore) {}
  ~MemoryPressureTask() override = default;
  MemoryPressureTask(const MemoryPressureTask&) = delete;
  MemoryPressureTask& operator=(const MemoryPressureTask&) = delete;

  // v8::Task implementation.
  void Run() override {
    isolate_->MemoryPressureNotification(MemoryPressureLevel::kCritical);
    semaphore_->Signal();
  }

 private:
  Isolate* isolate_;
  base::Semaphore* semaphore_;
};

}  // namespace

// Check that triggering a memory pressure notification on the isolate thread
// doesn't request a GC interrupt.
TEST_F(IsolateTest, MemoryPressureNotificationForeground) {
  internal::Isolate* i_isolate =
      reinterpret_cast<internal::Isolate*>(isolate());

  ASSERT_FALSE(i_isolate->stack_guard()->CheckGC());
  isolate()->MemoryPressureNotification(MemoryPressureLevel::kCritical);
  ASSERT_FALSE(i_isolate->stack_guard()->CheckGC());
}

// Check that triggering a memory pressure notification on an background thread
// requests a GC interrupt.
TEST_F(IsolateTest, MemoryPressureNotificationBackground) {
  internal::Isolate* i_isolate =
      reinterpret_cast<internal::Isolate*>(isolate());

  base::Semaphore semaphore(0);

  internal::V8::GetCurrentPlatform()->CallOnWorkerThread(
      std::make_unique<MemoryPressureTask>(isolate(), &semaphore));

  semaphore.Wait();

  ASSERT_TRUE(i_isolate->stack_guard()->CheckGC());
  v8::platform::PumpMessageLoop(internal::V8::GetCurrentPlatform(), isolate());
}

using IncumbentContextTest = TestWithIsolate;

// Check that Isolate::GetIncumbentContext() returns the correct one in basic
// scenarios.
TEST_F(IncumbentContextTest, Basic) {
  auto Str = [&](const char* s) {
    return String::NewFromUtf8(isolate(), s).ToLocalChecked();
  };
  auto Run = [&](Local<Context> context, const char* script) {
    Context::Scope scope(context);
    return Script::Compile(context, Str(script))
        .ToLocalChecked()
        ->Run(context)
        .ToLocalChecked();
  };

  // Set up the test environment; three contexts with getIncumbentGlobal()
  // function.
  Local<FunctionTemplate> get_incumbent_global = FunctionTemplate::New(
      isolate(), [](const FunctionCallbackInfo<Value>& info) {
        Local<Context> incumbent_context =
            info.GetIsolate()->GetIncumbentContext();
        info.GetReturnValue().Set(incumbent_context->Global());
      });
  Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate());
  global_template->Set(isolate(), "getIncumbentGlobal", get_incumbent_global);

  Local<Context> context_a = Context::New(isolate(), nullptr, global_template);
  Local<Context> context_b = Context::New(isolate(), nullptr, global_template);
  Local<Context> context_c = Context::New(isolate(), nullptr, global_template);
  Local<Object> global_a = context_a->Global();
  Local<Object> global_b = context_b->Global();
  Local<Object> global_c = context_c->Global();

  Local<String> security_token = Str("security_token");
  context_a->SetSecurityToken(security_token);
  context_b->SetSecurityToken(security_token);
  context_c->SetSecurityToken(security_token);

  global_a->Set(context_a, Str("b"), global_b).ToChecked();
  global_b->Set(context_b, Str("c"), global_c).ToChecked();

  // Test scenario 2: A -> B -> C, then the incumbent is C.
  Run(context_a, "funcA = function() { return b.funcB(); }");
  Run(context_b, "funcB = function() { return c.getIncumbentGlobal(); }");
  // Without BackupIncumbentScope.
  EXPECT_EQ(global_b, Run(context_a, "funcA()"));
  {
    // With BackupIncumbentScope.
    Context::BackupIncumbentScope backup_incumbent(context_a);
    EXPECT_EQ(global_b, Run(context_a, "funcA()"));
  }

  // Test scenario 2: A -> B -> C -> C, then the incumbent is C.
  Run(context_a, "funcA = function() { return b.funcB(); }");
  Run(context_b, "funcB = function() { return c.funcC(); }");
  Run(context_c, "funcC = function() { return getIncumbentGlobal(); }");
  // Without BackupIncumbentScope.
  EXPECT_EQ(global_c, Run(context_a, "funcA()"));
  {
    // With BackupIncumbentScope.
    Context::BackupIncumbentScope backup_incumbent(context_a);
    EXPECT_EQ(global_c, Run(context_a, "funcA()"));
  }
}

}  // namespace v8
