// 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/ScriptStreamer.h"

#include "bindings/core/v8/ScriptSourceCode.h"
#include "bindings/core/v8/ScriptStreamerThread.h"
#include "bindings/core/v8/ScriptStreamingMode.h"
#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8ScriptRunner.h"
#include "core/dom/PendingScript.h"
#include "core/frame/Settings.h"
#include "platform/Task.h"
#include "platform/heap/Handle.h"
#include "public/platform/Platform.h"

#include <gtest/gtest.h>
#include <v8.h>

namespace blink {

namespace {

// For the benefit of Oilpan, put the part object PendingScript inside
// a wrapper that's on the Oilpan heap and hold a reference to that wrapper
// from ScriptStreamingTest.
class PendingScriptWrapper : public NoBaseWillBeGarbageCollectedFinalized<PendingScriptWrapper> {
public:
    static PassOwnPtrWillBeRawPtr<PendingScriptWrapper> create()
    {
        return adoptPtrWillBeNoop(new PendingScriptWrapper());
    }

    static PassOwnPtrWillBeRawPtr<PendingScriptWrapper> create(Element* element, ScriptResource* resource)
    {
        return adoptPtrWillBeNoop(new PendingScriptWrapper(element, resource));
    }

    PendingScript& get() { return m_pendingScript; }

    void trace(Visitor* visitor)
    {
        visitor->trace(m_pendingScript);
    }

private:
    PendingScriptWrapper()
    {
    }

    PendingScriptWrapper(Element* element, ScriptResource* resource)
        : m_pendingScript(PendingScript(element, resource))
    {
    }

    PendingScript m_pendingScript;
};

// The bool param for ScriptStreamingTest controls whether to make the main
// thread block and wait for parsing.
class ScriptStreamingTest : public testing::TestWithParam<bool> {
public:
    ScriptStreamingTest()
        : m_scope(v8::Isolate::GetCurrent())
        , m_settings(Settings::create())
        , m_resourceRequest("http://www.streaming-test.com/")
        , m_resource(new ScriptResource(m_resourceRequest, "text/utf-8"))
        , m_pendingScript(PendingScriptWrapper::create(0, m_resource)) // Takes ownership of m_resource.
    {
        m_settings->setV8ScriptStreamingEnabled(true);
        if (GetParam())
            m_settings->setV8ScriptStreamingMode(ScriptStreamingModeAllPlusBlockParsingBlocking);
        m_resource->setLoading(true);
        ScriptStreamer::setSmallScriptThresholdForTesting(0);
    }

    ScriptState* scriptState() const { return m_scope.scriptState(); }
    v8::Isolate* isolate() const { return m_scope.isolate(); }

    PendingScript& pendingScript() const { return m_pendingScript->get(); }

protected:
    void appendData(const char* data)
    {
        m_resource->appendData(data, strlen(data));
        // Yield control to the background thread, so that V8 gets a change to
        // process the data before the main thread adds more. Note that we
        // cannot fully control in what kind of chunks the data is passed to V8
        // (if the V8 is not requesting more data between two appendData calls,
        // V8 will get both chunks together).
        Platform::current()->yieldCurrentThread();
    }

    void appendPadding()
    {
        for (int i = 0; i < 10; ++i) {
            appendData(" /* this is padding to make the script long enough, so "
                "that V8's buffer gets filled and it starts processing "
                "the data */ ");
        }
    }

    void finish()
    {
        m_resource->finish();
        m_resource->setLoading(false);
    }

    void processTasksUntilStreamingComplete()
    {
        WebThread* currentThread = blink::Platform::current()->currentThread();
        while (ScriptStreamerThread::shared()->isRunningTask()) {
            currentThread->postTask(new Task(WTF::bind(&WebThread::exitRunLoop, currentThread)));
            currentThread->enterRunLoop();
        }
        // Once more, because the "streaming complete" notification might only
        // now be in the task queue.
        currentThread->postTask(new Task(WTF::bind(&WebThread::exitRunLoop, currentThread)));
        currentThread->enterRunLoop();
    }

    V8TestingScope m_scope;
    OwnPtr<Settings> m_settings;
    // The Resource and PendingScript where we stream from. These don't really
    // fetch any data outside the test; the test controls the data by calling
    // ScriptResource::appendData.
    ResourceRequest m_resourceRequest;
    ScriptResource* m_resource;
    OwnPtrWillBePersistent<PendingScriptWrapper> m_pendingScript;
};

class TestScriptResourceClient : public ScriptResourceClient {
public:
    TestScriptResourceClient()
        : m_finished(false) { }

    virtual void notifyFinished(Resource*) override { m_finished = true; }

    bool finished() const { return m_finished; }

private:
    bool m_finished;
};

TEST_P(ScriptStreamingTest, CompilingStreamedScript)
{
    // Test that we can successfully compile a streamed script.
    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);

    appendData("function foo() {");
    appendPadding();
    appendData("return 5; }");
    appendPadding();
    appendData("foo();");
    EXPECT_FALSE(client.finished());
    finish();

    // Process tasks on the main thread until the streaming background thread
    // has completed its tasks.
    processTasksUntilStreamingComplete();
    EXPECT_TRUE(client.finished());
    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_TRUE(sourceCode.streamer());
    v8::TryCatch tryCatch;
    v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, isolate());
    EXPECT_FALSE(script.IsEmpty());
    EXPECT_FALSE(tryCatch.HasCaught());
}

TEST_P(ScriptStreamingTest, CompilingStreamedScriptWithParseError)
{
    // Test that scripts with parse errors are handled properly. In those cases,
    // the V8 side typically finished before loading finishes: make sure we
    // handle it gracefully.
    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);
    appendData("function foo() {");
    appendData("this is the part which will be a parse error");
    // V8 won't realize the parse error until it actually starts parsing the
    // script, and this happens only when its buffer is filled.
    appendPadding();

    EXPECT_FALSE(client.finished());

    // Force the V8 side to finish before the loading.
    processTasksUntilStreamingComplete();
    EXPECT_FALSE(client.finished());

    finish();
    EXPECT_TRUE(client.finished());

    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_TRUE(sourceCode.streamer());
    v8::TryCatch tryCatch;
    v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, isolate());
    EXPECT_TRUE(script.IsEmpty());
    EXPECT_TRUE(tryCatch.HasCaught());
}

TEST_P(ScriptStreamingTest, CancellingStreaming)
{
    // Test that the upper layers (PendingScript and up) can be ramped down
    // while streaming is ongoing, and ScriptStreamer handles it gracefully.
    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);
    appendData("function foo() {");

    // In general, we cannot control what the background thread is doing
    // (whether it's parsing or waiting for more data). In this test, we have
    // given it so little data that it's surely waiting for more.

    // Simulate cancelling the network load (e.g., because the user navigated
    // away).
    EXPECT_FALSE(client.finished());
    pendingScript().stopWatchingForLoad(&client);
    pendingScript().releaseElementAndClear();
    m_pendingScript = PendingScriptWrapper::create(); // This will destroy m_resource.
    m_resource = 0;

    // The V8 side will complete too. This should not crash. We don't receive
    // any results from the streaming and the client doesn't get notified.
    processTasksUntilStreamingComplete();
    EXPECT_FALSE(client.finished());
}

TEST_P(ScriptStreamingTest, SuppressingStreaming)
{
    // If we notice during streaming that there is a code cache, streaming
    // is suppressed (V8 doesn't parse while the script is loading), and the
    // upper layer (ScriptResourceClient) should get a notification when the
    // script is loaded.
    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);
    appendData("function foo() {");
    appendPadding();

    m_resource->setCachedMetadata(V8ScriptRunner::tagForCodeCache(), "X", 1, Resource::CacheLocally);

    appendPadding();
    finish();
    processTasksUntilStreamingComplete();
    EXPECT_TRUE(client.finished());

    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    // ScriptSourceCode doesn't refer to the streamer, since we have suppressed
    // the streaming and resumed the non-streaming code path for script
    // compilation.
    EXPECT_FALSE(sourceCode.streamer());
}

TEST_P(ScriptStreamingTest, EmptyScripts)
{
    // Empty scripts should also be streamed properly, that is, the upper layer
    // (ScriptResourceClient) should be notified when an empty script has been
    // loaded.
    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);

    // Finish the script without sending any data.
    finish();
    // The finished notification should arrive immediately and not be cycled
    // through a background thread.
    EXPECT_TRUE(client.finished());

    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_FALSE(sourceCode.streamer());
}

TEST_P(ScriptStreamingTest, SmallScripts)
{
    // Small scripts shouldn't be streamed.
    ScriptStreamer::setSmallScriptThresholdForTesting(100);

    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);

    appendData("function foo() { }");

    finish();

    // The finished notification should arrive immediately and not be cycled
    // through a background thread.
    EXPECT_TRUE(client.finished());

    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_FALSE(sourceCode.streamer());
}

TEST_P(ScriptStreamingTest, ScriptsWithSmallFirstChunk)
{
    // If a script is long enough, if should be streamed, even if the first data
    // chunk is small.
    ScriptStreamer::setSmallScriptThresholdForTesting(100);

    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);

    // This is the first data chunk which is small.
    appendData("function foo() { }");
    appendPadding();
    appendPadding();
    appendPadding();

    finish();

    processTasksUntilStreamingComplete();
    EXPECT_TRUE(client.finished());
    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_TRUE(sourceCode.streamer());
    v8::TryCatch tryCatch;
    v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, isolate());
    EXPECT_FALSE(script.IsEmpty());
    EXPECT_FALSE(tryCatch.HasCaught());
}

TEST_P(ScriptStreamingTest, EncodingChanges)
{
    // It's possible that the encoding of the Resource changes after we start
    // loading it.
    m_resource->setEncoding("windows-1252");

    ScriptStreamer::startStreaming(pendingScript(), m_settings.get(), m_scope.scriptState(), PendingScript::ParsingBlocking);
    TestScriptResourceClient client;
    pendingScript().watchForLoad(&client);

    m_resource->setEncoding("UTF-8");
    // \xec\x92\x81 are the raw bytes for \uc481.
    appendData("function foo() { var foob\xec\x92\x81r = 13; return foob\xec\x92\x81r; } foo();");

    finish();

    processTasksUntilStreamingComplete();
    EXPECT_TRUE(client.finished());
    bool errorOccurred = false;
    ScriptSourceCode sourceCode = pendingScript().getSource(KURL(), errorOccurred);
    EXPECT_FALSE(errorOccurred);
    EXPECT_TRUE(sourceCode.streamer());
    v8::TryCatch tryCatch;
    v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(sourceCode, isolate());
    EXPECT_FALSE(script.IsEmpty());
    EXPECT_FALSE(tryCatch.HasCaught());
}

INSTANTIATE_TEST_CASE_P(ScriptStreamingInstantiation, ScriptStreamingTest, ::testing::Values(false, true));

} // namespace

} // namespace blink
