// 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/base/template-utils.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;

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

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

  DISALLOW_COPY_AND_ASSIGN(MemoryPressureTask);
};

}  // 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(
      base::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, NewStringType::kNormal)
        .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(Str("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
