// Copyright 2014 The Chromium 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 "third_party/blink/renderer/bindings/core/v8/script_promise_property.h"

#include <memory>

#include "base/memory/scoped_refptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.h"
#include "third_party/blink/renderer/core/testing/gc_observation.h"
#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "v8/include/v8.h"

namespace blink {

namespace {

class NotReached : public ScriptFunction {
 public:
  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) {
    NotReached* self = MakeGarbageCollected<NotReached>(script_state);
    return self->BindToV8Function();
  }

  explicit NotReached(ScriptState* script_state)
      : ScriptFunction(script_state) {}

 private:
  ScriptValue Call(ScriptValue) override;
};

ScriptValue NotReached::Call(ScriptValue) {
  EXPECT_TRUE(false) << "'Unreachable' code was reached";
  return ScriptValue();
}

class StubFunction : public ScriptFunction {
 public:
  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
                                                ScriptValue& value,
                                                size_t& call_count) {
    StubFunction* self =
        MakeGarbageCollected<StubFunction>(script_state, value, call_count);
    return self->BindToV8Function();
  }

  StubFunction(ScriptState* script_state,
               ScriptValue& value,
               size_t& call_count)
      : ScriptFunction(script_state), value_(value), call_count_(call_count) {}

 private:
  ScriptValue Call(ScriptValue arg) override {
    value_ = arg;
    call_count_++;
    return ScriptValue();
  }

  ScriptValue& value_;
  size_t& call_count_;
};

class GarbageCollectedHolder final : public GarbageCollectedScriptWrappable {
 public:
  typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>,
                                Member<GarbageCollectedScriptWrappable>>
      Property;
  GarbageCollectedHolder(ExecutionContext* execution_context)
      : GarbageCollectedScriptWrappable("holder"),
        property_(MakeGarbageCollected<Property>(execution_context)) {}

  Property* GetProperty() { return property_; }
  GarbageCollectedScriptWrappable* ToGarbageCollectedScriptWrappable() {
    return this;
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(property_);
    GarbageCollectedScriptWrappable::Trace(visitor);
  }

 private:
  Member<Property> property_;
};

class ScriptPromisePropertyResetter : public ScriptFunction {
 public:
  using Property =
      ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>,
                            Member<GarbageCollectedScriptWrappable>>;
  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
                                                Property* property) {
    auto* self = MakeGarbageCollected<ScriptPromisePropertyResetter>(
        script_state, property);
    return self->BindToV8Function();
  }

  ScriptPromisePropertyResetter(ScriptState* script_state, Property* property)
      : ScriptFunction(script_state), property_(property) {}

  void Trace(Visitor* visitor) const override {
    visitor->Trace(property_);
    ScriptFunction::Trace(visitor);
  }

 private:
  ScriptValue Call(ScriptValue arg) override {
    property_->Reset();
    return ScriptValue();
  }

  const Member<Property> property_;
};

class ScriptPromisePropertyTestBase {
 public:
  ScriptPromisePropertyTestBase()
      : page_(std::make_unique<DummyPageHolder>(IntSize(1, 1))) {
    v8::HandleScope handle_scope(GetIsolate());
    other_script_state_ = MakeGarbageCollected<ScriptState>(
        v8::Context::New(GetIsolate()),
        DOMWrapperWorld::EnsureIsolatedWorld(GetIsolate(), 1),
        /* execution_context = */ nullptr);
  }

  virtual ~ScriptPromisePropertyTestBase() { DestroyContext(); }

  LocalDOMWindow* DomWindow() { return page_->GetFrame().DomWindow(); }
  v8::Isolate* GetIsolate() { return DomWindow()->GetIsolate(); }
  ScriptState* MainScriptState() {
    return ToScriptStateForMainWorld(&page_->GetFrame());
  }
  DOMWrapperWorld& MainWorld() { return MainScriptState()->World(); }
  ScriptState* OtherScriptState() { return other_script_state_; }
  DOMWrapperWorld& OtherWorld() { return other_script_state_->World(); }
  ScriptState* CurrentScriptState() {
    return ScriptState::Current(GetIsolate());
  }

  void DestroyContext() {
    page_.reset();
    if (other_script_state_) {
      other_script_state_->DisposePerContextData();
      other_script_state_ = nullptr;
    }
  }

  void Gc() { ThreadState::Current()->CollectAllGarbageForTesting(); }

  v8::Local<v8::Function> NotReached(ScriptState* script_state) {
    return NotReached::CreateFunction(script_state);
  }
  v8::Local<v8::Function> Stub(ScriptState* script_state,
                               ScriptValue& value,
                               size_t& call_count) {
    return StubFunction::CreateFunction(script_state, value, call_count);
  }

  template <typename T>
  ScriptValue Wrap(DOMWrapperWorld& world, const T& value) {
    v8::HandleScope handle_scope(GetIsolate());
    ScriptState* script_state =
        ScriptState::From(ToV8Context(DomWindow(), world));
    ScriptState::Scope scope(script_state);
    return ScriptValue(
        GetIsolate(),
        ToV8(value, script_state->GetContext()->Global(), GetIsolate()));
  }

 private:
  std::unique_ptr<DummyPageHolder> page_;
  Persistent<ScriptState> other_script_state_;
};

// This is the main test class.
// If you want to examine a testcase independent of holder types, place the
// test on this class.
class ScriptPromisePropertyGarbageCollectedTest
    : public ScriptPromisePropertyTestBase,
      public testing::Test {
 public:
  typedef GarbageCollectedHolder::Property Property;

  ScriptPromisePropertyGarbageCollectedTest()
      : holder_(MakeGarbageCollected<GarbageCollectedHolder>(DomWindow())) {}

  void ClearHolder() { holder_.Clear(); }
  GarbageCollectedHolder* Holder() { return holder_; }
  Property* GetProperty() { return holder_->GetProperty(); }
  ScriptPromise Promise(DOMWrapperWorld& world) {
    return GetProperty()->Promise(world);
  }

 private:
  Persistent<GarbageCollectedHolder> holder_;
};

// Tests that ScriptPromiseProperty works with a non ScriptWrappable resolution
// target.
class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest
    : public ScriptPromisePropertyTestBase,
      public testing::Test {
 public:
  template <typename T>
  void Test(const T& value, const char* expected, const char* file, int line) {
    typedef ScriptPromiseProperty<T, ToV8UndefinedGenerator> Property;
    Property* property = MakeGarbageCollected<Property>(DomWindow());
    size_t n_resolve_calls = 0;
    ScriptValue actual_value;
    String actual;
    {
      ScriptState::Scope scope(MainScriptState());
      property->Promise(DOMWrapperWorld::MainWorld())
          .Then(Stub(CurrentScriptState(), actual_value, n_resolve_calls),
                NotReached(CurrentScriptState()));
    }
    property->Resolve(value);
    v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
    {
      ScriptState::Scope scope(MainScriptState());
      actual = ToCoreString(actual_value.V8Value()
                                ->ToString(MainScriptState()->GetContext())
                                .ToLocalChecked());
    }
    if (expected != actual) {
      ADD_FAILURE_AT(file, line)
          << "toV8 returns an incorrect value.\n  Actual: " << actual.Utf8()
          << "\nExpected: " << expected;
      return;
    }
  }
};

}  // namespace

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       Promise_IsStableObjectInMainWorld) {
  ScriptPromise v = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  ScriptPromise w = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  EXPECT_EQ(v, w);
  ASSERT_FALSE(v.IsEmpty());
  {
    ScriptState::Scope scope(MainScriptState());
    EXPECT_EQ(v.V8Value().As<v8::Object>()->CreationContext(),
              ToV8Context(DomWindow(), MainWorld()));
  }
  EXPECT_EQ(Property::kPending, GetProperty()->GetState());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       Promise_IsStableObjectInVariousWorlds) {
  ScriptPromise u = GetProperty()->Promise(OtherWorld());
  ScriptPromise v = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  ScriptPromise w = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  EXPECT_NE(MainScriptState(), OtherScriptState());
  EXPECT_NE(&MainWorld(), &OtherWorld());
  EXPECT_NE(u, v);
  EXPECT_EQ(v, w);
  ASSERT_FALSE(u.IsEmpty());
  ASSERT_FALSE(v.IsEmpty());
  {
    ScriptState::Scope scope(OtherScriptState());
    EXPECT_EQ(u.V8Value().As<v8::Object>()->CreationContext(),
              ToV8Context(DomWindow(), OtherWorld()));
  }
  {
    ScriptState::Scope scope(MainScriptState());
    EXPECT_EQ(v.V8Value().As<v8::Object>()->CreationContext(),
              ToV8Context(DomWindow(), MainWorld()));
  }
  EXPECT_EQ(Property::kPending, GetProperty()->GetState());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       Promise_IsStableObjectAfterSettling) {
  ScriptPromise v = Promise(DOMWrapperWorld::MainWorld());
  GarbageCollectedScriptWrappable* value =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("value");

  GetProperty()->Resolve(value);
  EXPECT_EQ(Property::kResolved, GetProperty()->GetState());

  ScriptPromise w = Promise(DOMWrapperWorld::MainWorld());
  EXPECT_EQ(v, w);
  EXPECT_FALSE(v.IsEmpty());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       Promise_DoesNotImpedeGarbageCollection) {
  Persistent<GCObservation> observation;
  {
    ScriptState::Scope scope(MainScriptState());
    // Here we have a reference cylce between Holder() and the promise.
    Holder()->GetProperty()->Resolve(Holder());

    observation = MakeGarbageCollected<GCObservation>(
        Promise(DOMWrapperWorld::MainWorld()).V8Value());
  }

  Gc();
  EXPECT_FALSE(observation->wasCollected());

  ClearHolder();

  Gc();
  EXPECT_TRUE(observation->wasCollected());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       Resolve_ResolvesScriptPromise) {
  ScriptPromise promise = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  ScriptPromise other_promise = GetProperty()->Promise(OtherWorld());
  ScriptValue actual, other_actual;
  size_t n_resolve_calls = 0;
  size_t n_other_resolve_calls = 0;

  {
    ScriptState::Scope scope(MainScriptState());
    promise.Then(Stub(CurrentScriptState(), actual, n_resolve_calls),
                 NotReached(CurrentScriptState()));
  }

  {
    ScriptState::Scope scope(OtherScriptState());
    other_promise.Then(
        Stub(CurrentScriptState(), other_actual, n_other_resolve_calls),
        NotReached(CurrentScriptState()));
  }

  EXPECT_NE(promise, other_promise);

  GarbageCollectedScriptWrappable* value =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("value");
  GetProperty()->Resolve(value);
  EXPECT_EQ(Property::kResolved, GetProperty()->GetState());

  v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
  EXPECT_EQ(1u, n_resolve_calls);
  EXPECT_EQ(1u, n_other_resolve_calls);
  EXPECT_EQ(Wrap(MainWorld(), value), actual);
  EXPECT_NE(actual, other_actual);
  EXPECT_EQ(Wrap(OtherWorld(), value), other_actual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest,
       ResolveAndGetPromiseOnOtherWorld) {
  ScriptPromise promise = GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  ScriptPromise other_promise = GetProperty()->Promise(OtherWorld());
  ScriptValue actual, other_actual;
  size_t n_resolve_calls = 0;
  size_t n_other_resolve_calls = 0;

  {
    ScriptState::Scope scope(MainScriptState());
    promise.Then(Stub(CurrentScriptState(), actual, n_resolve_calls),
                 NotReached(CurrentScriptState()));
  }

  EXPECT_NE(promise, other_promise);
  GarbageCollectedScriptWrappable* value =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("value");
  GetProperty()->Resolve(value);
  EXPECT_EQ(Property::kResolved, GetProperty()->GetState());

  v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
  EXPECT_EQ(1u, n_resolve_calls);
  EXPECT_EQ(0u, n_other_resolve_calls);

  {
    ScriptState::Scope scope(OtherScriptState());
    other_promise.Then(
        Stub(CurrentScriptState(), other_actual, n_other_resolve_calls),
        NotReached(CurrentScriptState()));
  }

  v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
  EXPECT_EQ(1u, n_resolve_calls);
  EXPECT_EQ(1u, n_other_resolve_calls);
  EXPECT_EQ(Wrap(MainWorld(), value), actual);
  EXPECT_NE(actual, other_actual);
  EXPECT_EQ(Wrap(OtherWorld(), value), other_actual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reject_RejectsScriptPromise) {
  GarbageCollectedScriptWrappable* reason =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
  GetProperty()->Reject(reason);
  EXPECT_EQ(Property::kRejected, GetProperty()->GetState());

  ScriptValue actual, other_actual;
  size_t n_reject_calls = 0;
  size_t n_other_reject_calls = 0;
  {
    ScriptState::Scope scope(MainScriptState());
    GetProperty()
        ->Promise(DOMWrapperWorld::MainWorld())
        .Then(NotReached(CurrentScriptState()),
              Stub(CurrentScriptState(), actual, n_reject_calls));
  }

  {
    ScriptState::Scope scope(OtherScriptState());
    GetProperty()
        ->Promise(OtherWorld())
        .Then(NotReached(CurrentScriptState()),
              Stub(CurrentScriptState(), other_actual, n_other_reject_calls));
  }

  v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
  EXPECT_EQ(1u, n_reject_calls);
  EXPECT_EQ(Wrap(MainWorld(), reason), actual);
  EXPECT_EQ(1u, n_other_reject_calls);
  EXPECT_NE(actual, other_actual);
  EXPECT_EQ(Wrap(OtherWorld(), reason), other_actual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_DeadContext) {
  GetProperty()->Resolve(
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("value"));
  EXPECT_EQ(Property::kResolved, GetProperty()->GetState());

  DestroyContext();

  EXPECT_TRUE(GetProperty()->Promise(DOMWrapperWorld::MainWorld()).IsEmpty());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Resolve_DeadContext) {
  {
    ScriptState::Scope scope(MainScriptState());
    GetProperty()
        ->Promise(DOMWrapperWorld::MainWorld())
        .Then(NotReached(CurrentScriptState()),
              NotReached(CurrentScriptState()));
  }

  DestroyContext();
  EXPECT_TRUE(!GetProperty()->GetExecutionContext() ||
              GetProperty()->GetExecutionContext()->IsContextDestroyed());

  GetProperty()->Resolve(
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("value"));
  EXPECT_EQ(Property::kPending, GetProperty()->GetState());

  v8::MicrotasksScope::PerformCheckpoint(v8::Isolate::GetCurrent());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset) {
  ScriptState::Scope scope(MainScriptState());

  ScriptPromise old_promise, new_promise;
  ScriptValue old_actual, new_actual;
  GarbageCollectedScriptWrappable* old_value =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("old");
  GarbageCollectedScriptWrappable* new_value =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("new");
  size_t n_old_resolve_calls = 0;
  size_t n_new_reject_calls = 0;

  {
    ScriptState::Scope scope(MainScriptState());
    GetProperty()->Resolve(old_value);
    old_promise = GetProperty()->Promise(MainWorld());
    old_promise.Then(
        Stub(CurrentScriptState(), old_actual, n_old_resolve_calls),
        NotReached(CurrentScriptState()));
  }

  GetProperty()->Reset();

  {
    ScriptState::Scope scope(MainScriptState());
    new_promise = GetProperty()->Promise(MainWorld());
    new_promise.Then(
        NotReached(CurrentScriptState()),
        Stub(CurrentScriptState(), new_actual, n_new_reject_calls));
    GetProperty()->Reject(new_value);
  }

  EXPECT_EQ(0u, n_old_resolve_calls);
  EXPECT_EQ(0u, n_new_reject_calls);

  v8::MicrotasksScope::PerformCheckpoint(GetIsolate());
  EXPECT_EQ(1u, n_old_resolve_calls);
  EXPECT_EQ(1u, n_new_reject_calls);
  EXPECT_NE(old_promise, new_promise);
  EXPECT_EQ(Wrap(MainWorld(), old_value), old_actual);
  EXPECT_EQ(Wrap(MainWorld(), new_value), new_actual);
  EXPECT_NE(old_actual, new_actual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, MarkAsHandled) {
  {
    // Unhandled promise.
    ScriptState::Scope scope(MainScriptState());
    ScriptPromise promise =
        GetProperty()->Promise(DOMWrapperWorld::MainWorld());
    GarbageCollectedScriptWrappable* reason =
        MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
    GetProperty()->Reject(reason);
    EXPECT_FALSE(promise.V8Promise()->HasHandler());
  }

  GetProperty()->Reset();

  {
    // MarkAsHandled applies to newly created promises.
    ScriptState::Scope scope(MainScriptState());
    GetProperty()->MarkAsHandled();
    ScriptPromise promise =
        GetProperty()->Promise(DOMWrapperWorld::MainWorld());
    GarbageCollectedScriptWrappable* reason =
        MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
    GetProperty()->Reject(reason);
    EXPECT_TRUE(promise.V8Promise()->HasHandler());
  }

  GetProperty()->Reset();

  {
    // MarkAsHandled applies to previously vended promises.
    ScriptState::Scope scope(MainScriptState());
    ScriptPromise promise =
        GetProperty()->Promise(DOMWrapperWorld::MainWorld());
    GetProperty()->MarkAsHandled();
    GarbageCollectedScriptWrappable* reason =
        MakeGarbageCollected<GarbageCollectedScriptWrappable>("reason");
    GetProperty()->Reject(reason);
    EXPECT_TRUE(promise.V8Promise()->HasHandler());
  }
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, SyncResolve) {
  // Call getters to create resolvers in the property.
  GetProperty()->Promise(DOMWrapperWorld::MainWorld());
  GetProperty()->Promise(OtherWorld());

  auto* resolution =
      MakeGarbageCollected<GarbageCollectedScriptWrappable>("hi");
  v8::HandleScope handle_scope(GetIsolate());
  v8::Local<v8::Object> main_v8_resolution;
  v8::Local<v8::Object> other_v8_resolution;
  {
    ScriptState::Scope scope(MainScriptState());
    main_v8_resolution = ToV8(resolution, MainScriptState()).As<v8::Object>();
    v8::PropertyDescriptor descriptor(
        ScriptPromisePropertyResetter::CreateFunction(MainScriptState(),
                                                      GetProperty()),
        v8::Undefined(GetIsolate()));
    ASSERT_EQ(
        v8::Just(true),
        main_v8_resolution->DefineProperty(
            MainScriptState()->GetContext(),
            v8::String::NewFromUtf8Literal(GetIsolate(), "then"), descriptor));
  }
  {
    ScriptState::Scope scope(OtherScriptState());
    other_v8_resolution = ToV8(resolution, OtherScriptState()).As<v8::Object>();
    v8::PropertyDescriptor descriptor(
        ScriptPromisePropertyResetter::CreateFunction(OtherScriptState(),
                                                      GetProperty()),
        v8::Undefined(GetIsolate()));
    ASSERT_EQ(
        v8::Just(true),
        other_v8_resolution->DefineProperty(
            OtherScriptState()->GetContext(),
            v8::String::NewFromUtf8Literal(GetIsolate(), "then"), descriptor));
  }

  // This shouldn't crash.
  GetProperty()->Resolve(resolution);
  EXPECT_EQ(GetProperty()->GetState(), Property::State::kPending);
}

TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest,
       ResolveWithUndefined) {
  Test(ToV8UndefinedGenerator(), "undefined", __FILE__, __LINE__);
}

TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest,
       ResolveWithString) {
  Test(String("hello"), "hello", __FILE__, __LINE__);
}

TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest,
       ResolveWithInteger) {
  Test(-1, "-1", __FILE__, __LINE__);
}

}  // namespace blink
