// 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 "config.h"
#include "bindings/core/v8/ScriptPromiseProperty.h"

#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/ScriptFunction.h"
#include "bindings/core/v8/ScriptPromise.h"
#include "bindings/core/v8/ScriptState.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8GCController.h"
#include "core/dom/Document.h"
#include "core/testing/DummyPageHolder.h"
#include "core/testing/GCObservation.h"
#include "core/testing/GarbageCollectedScriptWrappable.h"
#include "core/testing/RefCountedScriptWrappable.h"
#include "platform/heap/Handle.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include <gtest/gtest.h>
#include <v8.h>

using namespace blink;

namespace {

class NotReached : public ScriptFunction {
public:
    static v8::Handle<v8::Function> createFunction(ScriptState* scriptState)
    {
        NotReached* self = new NotReached(scriptState);
        return self->bindToV8Function();
    }

private:
    explicit NotReached(ScriptState* scriptState)
        : ScriptFunction(scriptState)
    {
    }

    virtual ScriptValue call(ScriptValue) override;
};

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

class StubFunction : public ScriptFunction {
public:
    static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, ScriptValue& value, size_t& callCount)
    {
        StubFunction* self = new StubFunction(scriptState, value, callCount);
        return self->bindToV8Function();
    }

private:
    StubFunction(ScriptState* scriptState, ScriptValue& value, size_t& callCount)
        : ScriptFunction(scriptState)
        , m_value(value)
        , m_callCount(callCount)
    {
    }

    virtual ScriptValue call(ScriptValue arg) override
    {
        m_value = arg;
        m_callCount++;
        return ScriptValue();
    }

    ScriptValue& m_value;
    size_t& m_callCount;
};

class GarbageCollectedHolder : public GarbageCollectedScriptWrappable {
public:
    typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, Member<GarbageCollectedScriptWrappable>, Member<GarbageCollectedScriptWrappable> > Property;
    GarbageCollectedHolder(ExecutionContext* executionContext)
        : GarbageCollectedScriptWrappable("holder")
        , m_property(new Property(executionContext, toGarbageCollectedScriptWrappable(), Property::Ready)) { }

    Property* property() { return m_property; }
    GarbageCollectedScriptWrappable* toGarbageCollectedScriptWrappable() { return this; }

    virtual void trace(Visitor *visitor) override
    {
        GarbageCollectedScriptWrappable::trace(visitor);
        visitor->trace(m_property);
    }

private:
    Member<Property> m_property;
};

class RefCountedHolder : public RefCountedScriptWrappable {
public:
    // Do not resolve or reject the property with the holder itself. It leads
    // to a leak.
    typedef ScriptPromiseProperty<RefCountedScriptWrappable*, RefPtr<RefCountedScriptWrappable>, RefPtr<RefCountedScriptWrappable> > Property;
    static PassRefPtr<RefCountedHolder> create(ExecutionContext* executionContext)
    {
        return adoptRef(new RefCountedHolder(executionContext));
    }
    Property* property() { return m_property; }
    RefCountedScriptWrappable* toRefCountedScriptWrappable() { return this; }

private:
    RefCountedHolder(ExecutionContext* executionContext)
        : RefCountedScriptWrappable("holder")
        , m_property(new Property(executionContext, toRefCountedScriptWrappable(), Property::Ready)) { }

    Persistent<Property> m_property;
};

class ScriptPromisePropertyTestBase {
public:
    ScriptPromisePropertyTestBase()
        : m_page(DummyPageHolder::create(IntSize(1, 1)))
    {
        v8::HandleScope handleScope(isolate());
        m_otherScriptState = ScriptStateForTesting::create(v8::Context::New(isolate()), DOMWrapperWorld::create(1));
    }

    virtual ~ScriptPromisePropertyTestBase()
    {
        m_page.clear();
        gc();
        Heap::collectAllGarbage();
    }

    Document& document() { return m_page->document(); }
    v8::Isolate* isolate() { return toIsolate(&document()); }
    ScriptState* mainScriptState() { return ScriptState::forMainWorld(document().frame()); }
    DOMWrapperWorld& mainWorld() { return mainScriptState()->world(); }
    ScriptState* otherScriptState() { return m_otherScriptState.get(); }
    DOMWrapperWorld& otherWorld() { return m_otherScriptState->world(); }
    ScriptState* currentScriptState() { return ScriptState::current(isolate()); }

    virtual void destroyContext()
    {
        m_page.clear();
        m_otherScriptState.clear();
        gc();
        Heap::collectGarbage(ThreadState::HeapPointersOnStack);
    }

    void gc() { V8GCController::collectGarbage(v8::Isolate::GetCurrent()); }

    v8::Handle<v8::Function> notReached(ScriptState* scriptState) { return NotReached::createFunction(scriptState); }
    v8::Handle<v8::Function> stub(ScriptState* scriptState, ScriptValue& value, size_t& callCount) { return StubFunction::createFunction(scriptState, value, callCount); }

    template <typename T>
    ScriptValue wrap(DOMWrapperWorld& world, const T& value)
    {
        v8::HandleScope handleScope(isolate());
        ScriptState* scriptState = ScriptState::from(toV8Context(&document(), world));
        ScriptState::Scope scope(scriptState);
        return ScriptValue(scriptState, V8ValueTraits<T>::toV8Value(value, scriptState->context()->Global(), isolate()));
    }

private:
    OwnPtr<DummyPageHolder> m_page;
    RefPtr<ScriptState> m_otherScriptState;
};

// 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()
        : m_holder(new GarbageCollectedHolder(&document()))
    {
    }

    GarbageCollectedHolder* holder() { return m_holder; }
    Property* property() { return m_holder->property(); }
    ScriptPromise promise(DOMWrapperWorld& world) { return property()->promise(world); }

    virtual void destroyContext() override
    {
        m_holder = nullptr;
        ScriptPromisePropertyTestBase::destroyContext();
    }

private:
    Persistent<GarbageCollectedHolder> m_holder;
};

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectInMainWorld)
{
    ScriptPromise v = property()->promise(DOMWrapperWorld::mainWorld());
    ScriptPromise w = property()->promise(DOMWrapperWorld::mainWorld());
    EXPECT_EQ(v, w);
    ASSERT_FALSE(v.isEmpty());
    {
        ScriptState::Scope scope(mainScriptState());
        EXPECT_EQ(v.v8Value().As<v8::Object>()->CreationContext(), toV8Context(&document(), mainWorld()));
    }
    EXPECT_EQ(Property::Pending, property()->state());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectInVariousWorlds)
{
    ScriptPromise u = property()->promise(otherWorld());
    ScriptPromise v = property()->promise(DOMWrapperWorld::mainWorld());
    ScriptPromise w = property()->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(&document(), otherWorld()));
    }
    {
        ScriptState::Scope scope(mainScriptState());
        EXPECT_EQ(v.v8Value().As<v8::Object>()->CreationContext(), toV8Context(&document(), mainWorld()));
    }
    EXPECT_EQ(Property::Pending, property()->state());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_IsStableObjectAfterSettling)
{
    ScriptPromise v = promise(DOMWrapperWorld::mainWorld());
    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");

    property()->resolve(value);
    EXPECT_EQ(Property::Resolved, property()->state());

    ScriptPromise w = promise(DOMWrapperWorld::mainWorld());
    EXPECT_EQ(v, w);
    EXPECT_FALSE(v.isEmpty());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_DoesNotImpedeGarbageCollection)
{
    ScriptValue holderWrapper = wrap(mainWorld(), holder()->toGarbageCollectedScriptWrappable());

    Persistent<GCObservation> observation;
    {
        ScriptState::Scope scope(mainScriptState());
        observation = GCObservation::create(promise(DOMWrapperWorld::mainWorld()).v8Value());
    }

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

    holderWrapper.clear();
    gc();
    EXPECT_TRUE(observation->wasCollected());

    EXPECT_EQ(Property::Pending, property()->state());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Resolve_ResolvesScriptPromise)
{
    ScriptPromise promise = property()->promise(DOMWrapperWorld::mainWorld());
    ScriptPromise otherPromise = property()->promise(otherWorld());
    ScriptValue actual, otherActual;
    size_t nResolveCalls = 0;
    size_t nOtherResolveCalls = 0;

    {
        ScriptState::Scope scope(mainScriptState());
        promise.then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
    }

    {
        ScriptState::Scope scope(otherScriptState());
        otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
    }

    EXPECT_NE(promise, otherPromise);

    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");
    property()->resolve(value);
    EXPECT_EQ(Property::Resolved, property()->state());

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nResolveCalls);
    EXPECT_EQ(1u, nOtherResolveCalls);
    EXPECT_EQ(wrap(mainWorld(), value), actual);
    EXPECT_NE(actual, otherActual);
    EXPECT_EQ(wrap(otherWorld(), value), otherActual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, ResolveAndGetPromiseOnOtherWorld)
{
    ScriptPromise promise = property()->promise(DOMWrapperWorld::mainWorld());
    ScriptPromise otherPromise = property()->promise(otherWorld());
    ScriptValue actual, otherActual;
    size_t nResolveCalls = 0;
    size_t nOtherResolveCalls = 0;

    {
        ScriptState::Scope scope(mainScriptState());
        promise.then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
    }

    EXPECT_NE(promise, otherPromise);
    GarbageCollectedScriptWrappable* value = new GarbageCollectedScriptWrappable("value");
    property()->resolve(value);
    EXPECT_EQ(Property::Resolved, property()->state());

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nResolveCalls);
    EXPECT_EQ(0u, nOtherResolveCalls);

    {
        ScriptState::Scope scope(otherScriptState());
        otherPromise.then(stub(currentScriptState(), otherActual, nOtherResolveCalls), notReached(currentScriptState()));
    }

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nResolveCalls);
    EXPECT_EQ(1u, nOtherResolveCalls);
    EXPECT_EQ(wrap(mainWorld(), value), actual);
    EXPECT_NE(actual, otherActual);
    EXPECT_EQ(wrap(otherWorld(), value), otherActual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reject_RejectsScriptPromise)
{
    GarbageCollectedScriptWrappable* reason = new GarbageCollectedScriptWrappable("reason");
    property()->reject(reason);
    EXPECT_EQ(Property::Rejected, property()->state());

    ScriptValue actual, otherActual;
    size_t nRejectCalls = 0;
    size_t nOtherRejectCalls = 0;
    {
        ScriptState::Scope scope(mainScriptState());
        property()->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), actual, nRejectCalls));
    }

    {
        ScriptState::Scope scope(otherScriptState());
        property()->promise(otherWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), otherActual, nOtherRejectCalls));
    }

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nRejectCalls);
    EXPECT_EQ(wrap(mainWorld(), reason), actual);
    EXPECT_EQ(1u, nOtherRejectCalls);
    EXPECT_NE(actual, otherActual);
    EXPECT_EQ(wrap(otherWorld(), reason), otherActual);
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Promise_DeadContext)
{
    Property* property = this->property();
    property->resolve(new GarbageCollectedScriptWrappable("value"));
    EXPECT_EQ(Property::Resolved, property->state());

    destroyContext();

    EXPECT_TRUE(property->promise(DOMWrapperWorld::mainWorld()).isEmpty());
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Resolve_DeadContext)
{
    Property* property = this->property();

    {
        ScriptState::Scope scope(mainScriptState());
        property->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), notReached(currentScriptState()));
    }

    destroyContext();
    EXPECT_TRUE(!property->executionContext() || property->executionContext()->activeDOMObjectsAreStopped());

    property->resolve(new GarbageCollectedScriptWrappable("value"));
    EXPECT_EQ(Property::Pending, property->state());

    v8::Isolate::GetCurrent()->RunMicrotasks();
}

TEST_F(ScriptPromisePropertyGarbageCollectedTest, Reset)
{
    ScriptPromise oldPromise, newPromise;
    ScriptValue oldActual, newActual;
    GarbageCollectedScriptWrappable* oldValue = new GarbageCollectedScriptWrappable("old");
    GarbageCollectedScriptWrappable* newValue = new GarbageCollectedScriptWrappable("new");
    size_t nOldResolveCalls = 0;
    size_t nNewRejectCalls = 0;

    {
        ScriptState::Scope scope(mainScriptState());
        property()->resolve(oldValue);
        oldPromise = property()->promise(mainWorld());
        oldPromise.then(stub(currentScriptState(), oldActual, nOldResolveCalls), notReached(currentScriptState()));
    }

    property()->reset();

    {
        ScriptState::Scope scope(mainScriptState());
        newPromise = property()->promise(mainWorld());
        newPromise.then(notReached(currentScriptState()), stub(currentScriptState(), newActual, nNewRejectCalls));
        property()->reject(newValue);
    }

    EXPECT_EQ(0u, nOldResolveCalls);
    EXPECT_EQ(0u, nNewRejectCalls);

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nOldResolveCalls);
    EXPECT_EQ(1u, nNewRejectCalls);
    EXPECT_NE(oldPromise, newPromise);
    EXPECT_EQ(wrap(mainWorld(), oldValue), oldActual);
    EXPECT_EQ(wrap(mainWorld(), newValue), newActual);
    EXPECT_NE(oldActual, newActual);
}

// Tests that ScriptPromiseProperty works with a ref-counted holder.
class ScriptPromisePropertyRefCountedTest : public ScriptPromisePropertyTestBase, public ::testing::Test {
public:
    typedef RefCountedHolder::Property Property;

    ScriptPromisePropertyRefCountedTest()
        : m_holder(RefCountedHolder::create(&document()))
    {
    }

    RefCountedHolder* holder() { return m_holder.get(); }
    Property* property() { return m_holder->property(); }

private:
    RefPtr<RefCountedHolder> m_holder;
};

TEST_F(ScriptPromisePropertyRefCountedTest, Resolve)
{
    ScriptValue actual;
    size_t nResolveCalls = 0;

    {
        ScriptState::Scope scope(mainScriptState());
        property()->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actual, nResolveCalls), notReached(currentScriptState()));
    }

    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");
    property()->resolve(value.get());
    EXPECT_EQ(Property::Resolved, property()->state());

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nResolveCalls);
    EXPECT_EQ(wrap(mainWorld(), value), actual);
}

TEST_F(ScriptPromisePropertyRefCountedTest, Reject)
{
    ScriptValue actual;
    size_t nRejectCalls = 0;

    {
        ScriptState::Scope scope(mainScriptState());
        property()->promise(DOMWrapperWorld::mainWorld()).then(notReached(currentScriptState()), stub(currentScriptState(), actual, nRejectCalls));
    }

    RefPtr<RefCountedScriptWrappable> reason = RefCountedScriptWrappable::create("reason");
    property()->reject(reason);
    EXPECT_EQ(Property::Rejected, property()->state());

    isolate()->RunMicrotasks();
    EXPECT_EQ(1u, nRejectCalls);
    EXPECT_EQ(wrap(mainWorld(), reason), actual);
}

TEST_F(ScriptPromisePropertyRefCountedTest, ReSolveAndReset)
{
    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");

    {
        ScriptState::Scope scope(mainScriptState());
        property()->resolve(value);
    }

    EXPECT_EQ(2, value->refCount());
    property()->reset();
    EXPECT_EQ(1, value->refCount());
}

TEST_F(ScriptPromisePropertyRefCountedTest, RejectAndReset)
{
    RefPtr<RefCountedScriptWrappable> value = RefCountedScriptWrappable::create("value");

    {
        ScriptState::Scope scope(mainScriptState());
        property()->reject(value.get());
    }

    EXPECT_EQ(2, value->refCount());
    property()->reset();
    EXPECT_EQ(1, value->refCount());
}

// 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, size_t line)
    {
        typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T, V8UndefinedType> Property;
        Property* property = new Property(&document(), new GarbageCollectedScriptWrappable("holder"), Property::Ready);
        size_t nResolveCalls = 0;
        ScriptValue actualValue;
        String actual;
        {
            ScriptState::Scope scope(mainScriptState());
            property->promise(DOMWrapperWorld::mainWorld()).then(stub(currentScriptState(), actualValue, nResolveCalls), notReached(currentScriptState()));
        }
        property->resolve(value);
        isolate()->RunMicrotasks();
        {
            ScriptState::Scope scope(mainScriptState());
            actual = toCoreString(actualValue.v8Value()->ToString());
        }
        if (expected != actual) {
            ADD_FAILURE_AT(file, line) << "toV8Value returns an incorrect value.\n  Actual: " << actual.utf8().data() << "\nExpected: " << expected;
            return;
        }
    }
};

TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithUndefined)
{
    test(V8UndefinedType(), "undefined", __FILE__, __LINE__);
}

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

TEST_F(ScriptPromisePropertyNonScriptWrappableResolutionTargetTest, ResolveWithInteger)
{
    test<int>(-1, "-1", __FILE__, __LINE__);
}

} // namespace
