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

#include <memory>
#include <utility>

#include "base/single_thread_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/platform/web_url_request_extra_data.h"
#include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.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_code_cache.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/script/classic_pending_script.h"
#include "third_party/blink/renderer/core/script/classic_script.h"
#include "third_party/blink/renderer/core/script/mock_script_element_base.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/cross_origin_attribute_value.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h"
#include "third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h"
#include "third_party/blink/renderer/platform/loader/testing/test_resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/text/text_encoding.h"
#include "v8/include/v8.h"

namespace blink {

namespace {

class TestResourceClient final : public GarbageCollected<TestResourceClient>,
                                 public ResourceClient {

 public:
  TestResourceClient() : finished_(false) {}
  bool Finished() const { return finished_; }

  void DataReceived(Resource*,
                    const char* /* data */,
                    size_t /* length */) override {}
  void NotifyFinished(Resource*) override { finished_ = true; }

  // Name for debugging, e.g. shown in memory-infra.
  String DebugName() const override { return "TestResourceClient"; }

 private:
  bool finished_;
};

// TODO(leszeks): This class has a similar class in resource_loader_test.cc,
// the two should probably share the same class.
class NoopLoaderFactory final : public ResourceFetcher::LoaderFactory {
  std::unique_ptr<WebURLLoader> CreateURLLoader(
      const ResourceRequest& request,
      const ResourceLoaderOptions& options,
      scoped_refptr<base::SingleThreadTaskRunner>,
      scoped_refptr<base::SingleThreadTaskRunner>,
      WebBackForwardCacheLoaderHelper) override {
    return std::make_unique<NoopWebURLLoader>();
  }
  std::unique_ptr<WebCodeCacheLoader> CreateCodeCacheLoader() override {
    return Platform::Current()->CreateCodeCacheLoader();
  }

  class NoopWebURLLoader final : public WebURLLoader {
   public:
    ~NoopWebURLLoader() override = default;
    void LoadSynchronously(
        std::unique_ptr<network::ResourceRequest> request,
        scoped_refptr<WebURLRequestExtraData> url_request_extra_data,
        int requestor_id,
        bool pass_response_pipe_to_client,
        bool no_mime_sniffing,
        base::TimeDelta timeout_interval,
        WebURLLoaderClient*,
        WebURLResponse&,
        base::Optional<WebURLError>&,
        WebData&,
        int64_t& encoded_data_length,
        int64_t& encoded_body_length,
        WebBlobInfo& downloaded_blob,
        std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
            resource_load_info_notifier_wrapper) override {
      NOTREACHED();
    }
    void LoadAsynchronously(
        std::unique_ptr<network::ResourceRequest> request,
        scoped_refptr<WebURLRequestExtraData> url_request_extra_data,
        int requestor_id,
        bool no_mime_sniffing,
        std::unique_ptr<blink::ResourceLoadInfoNotifierWrapper>
            resource_load_info_notifier_wrapper,
        WebURLLoaderClient*) override {}
    void SetDefersLoading(WebURLLoader::DeferType) override {}
    void DidChangePriority(WebURLRequest::Priority, int) override {
      NOTREACHED();
    }
    scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForBodyLoader()
        override {
      return base::MakeRefCounted<scheduler::FakeTaskRunner>();
    }
  };
};

class ScriptStreamingTest : public testing::Test {
 public:
  ScriptStreamingTest()
      : url_("http://www.streaming-test.com/"),
        freezable_task_runner_(platform_->test_task_runner()),
        unfreezable_task_runner_(platform_->test_task_runner()) {
    auto* properties = MakeGarbageCollected<TestResourceFetcherProperties>();
    FetchContext* context = MakeGarbageCollected<MockFetchContext>();
    auto* fetcher = MakeGarbageCollected<ResourceFetcher>(ResourceFetcherInit(
        properties->MakeDetachable(), context, freezable_task_runner_,
        unfreezable_task_runner_, MakeGarbageCollected<NoopLoaderFactory>(),
        MakeGarbageCollected<MockContextLifecycleNotifier>(),
        nullptr /* back_forward_cache_loader_helper */));

    EXPECT_EQ(mojo::CreateDataPipe(nullptr, producer_handle_, consumer_handle_),
              MOJO_RESULT_OK);

    ResourceRequest request(url_);
    request.SetRequestContext(mojom::blink::RequestContextType::SCRIPT);

    resource_client_ = MakeGarbageCollected<TestResourceClient>();
    FetchParameters params = FetchParameters::CreateForTest(std::move(request));
    resource_ = ScriptResource::Fetch(params, fetcher, resource_client_,
                                      ScriptResource::kAllowStreaming);
    resource_->AddClient(resource_client_, freezable_task_runner_.get());

    ScriptStreamer::SetSmallScriptThresholdForTesting(0);

    ResourceResponse response(url_);
    response.SetHttpStatusCode(200);
    resource_->SetResponse(response);

    resource_->Loader()->DidReceiveResponse(WrappedResourceResponse(response));
    resource_->Loader()->DidStartLoadingResponseBody(
        std::move(consumer_handle_));
  }

  ScriptSourceCode GetScriptSourceCode() const {
    ScriptStreamer* streamer = resource_->TakeStreamer();
    if (streamer) {
      if (streamer->IsStreamingSuppressed()) {
        return ScriptSourceCode(nullptr, resource_,
                                streamer->StreamingSuppressedReason());
      }
      return ScriptSourceCode(streamer, resource_,
                              ScriptStreamer::NotStreamingReason::kInvalid);
    }
    return ScriptSourceCode(nullptr, resource_, resource_->NoStreamerReason());
  }

  Settings* GetSettings() const {
    return &dummy_page_holder_->GetPage().GetSettings();
  }

 protected:
  void AppendData(const char* data) {
    uint32_t data_len = strlen(data);
    MojoResult result = producer_handle_->WriteData(
        data, &data_len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
    EXPECT_EQ(result, MOJO_RESULT_OK);

    // Yield control to the background thread, so that V8 gets a chance 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 V8 is not requesting more data between two appendData calls, it
    // will get both chunks together).
    test::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() {
    resource_->Loader()->DidFinishLoading(base::TimeTicks(), 0, 0, 0, false);
    producer_handle_.reset();
    resource_->SetStatus(ResourceStatus::kCached);
  }

  void ProcessTasksUntilStreamingComplete() { platform_->RunUntilIdle(); }

  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform_;

  KURL url_;
  scoped_refptr<base::SingleThreadTaskRunner> freezable_task_runner_;
  scoped_refptr<base::SingleThreadTaskRunner> unfreezable_task_runner_;

  Persistent<TestResourceClient> resource_client_;
  Persistent<ScriptResource> resource_;
  mojo::ScopedDataPipeProducerHandle producer_handle_;
  mojo::ScopedDataPipeConsumerHandle consumer_handle_;

  std::unique_ptr<DummyPageHolder> dummy_page_holder_;
};

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScript) {
  // Test that we can successfully compile a streamed script.
  V8TestingScope scope;

  AppendData("function foo() {");
  AppendPadding();
  AppendData("return 5; }");
  AppendPadding();
  AppendData("foo();");
  EXPECT_FALSE(resource_client_->Finished());
  Finish();

  // Process tasks on the main thread until the streaming background thread
  // has completed its tasks.
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());
  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_TRUE(source_code.Streamer());
  v8::TryCatch try_catch(scope.GetIsolate());
  v8::Local<v8::Script> script;
  v8::ScriptCompiler::CompileOptions compile_options;
  V8CodeCache::ProduceCacheOptions produce_cache_options;
  v8::ScriptCompiler::NoCacheReason no_cache_reason;
  std::tie(compile_options, produce_cache_options, no_cache_reason) =
      V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault,
                                     source_code);
  EXPECT_TRUE(V8ScriptRunner::CompileScript(
                  scope.GetScriptState(), source_code,
                  SanitizeScriptErrors::kDoNotSanitize, compile_options,
                  no_cache_reason, ReferrerScriptInfo())
                  .ToLocal(&script));
  EXPECT_FALSE(try_catch.HasCaught());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScriptWithParseError) {
  // Test that scripts with parse errors are handled properly. In those cases,
  // V8 stops reading the network stream: make sure we handle it gracefully.
  V8TestingScope scope;
  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(resource_client_->Finished());
  Finish();

  // Process tasks on the main thread until the streaming background thread
  // has completed its tasks.
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());
  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_TRUE(source_code.Streamer());
  v8::TryCatch try_catch(scope.GetIsolate());
  v8::Local<v8::Script> script;
  v8::ScriptCompiler::CompileOptions compile_options;
  V8CodeCache::ProduceCacheOptions produce_cache_options;
  v8::ScriptCompiler::NoCacheReason no_cache_reason;
  std::tie(compile_options, produce_cache_options, no_cache_reason) =
      V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault,
                                     source_code);
  EXPECT_FALSE(V8ScriptRunner::CompileScript(
                   scope.GetScriptState(), source_code,
                   SanitizeScriptErrors::kDoNotSanitize, compile_options,
                   no_cache_reason, ReferrerScriptInfo())
                   .ToLocal(&script));
  EXPECT_TRUE(try_catch.HasCaught());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_CancellingStreaming) {
  // Test that the upper layers (PendingScript and up) can be ramped down
  // while streaming is ongoing, and ScriptStreamer handles it gracefully.
  V8TestingScope scope;
  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(resource_client_->Finished());
  resource_ = nullptr;

  // 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(resource_client_->Finished());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_DataAfterDisposingPendingScript) {
  // Test that the upper layers (PendingScript and up) can be ramped down
  // before streaming is started, and ScriptStreamer handles it gracefully.
  V8TestingScope scope;

  // 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.

  EXPECT_FALSE(resource_client_->Finished());

  // Keep the resource alive
  Persistent<ScriptResource> resource = resource_;

  // Simulate cancelling the network load (e.g., because the user navigated
  // away).
  resource_ = nullptr;

  // Make sure the streaming starts.
  AppendData("function foo() {");
  AppendPadding();
  resource.Clear();

  // 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(resource_client_->Finished());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_SuppressingStreaming) {
  // If we notice before 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.
  V8TestingScope scope;

  SingleCachedMetadataHandler* cache_handler = resource_->CacheHandler();
  EXPECT_TRUE(cache_handler);
  cache_handler->DisableSendToPlatformForTesting();
  cache_handler->SetCachedMetadata(V8CodeCache::TagForCodeCache(cache_handler),
                                   reinterpret_cast<const uint8_t*>("X"), 1);

  AppendData("function foo() {");
  AppendPadding();
  Finish();
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());

  ScriptSourceCode source_code = GetScriptSourceCode();
  // 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(source_code.Streamer());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_EmptyScripts) {
  // Empty scripts should also be streamed properly, that is, the upper layer
  // (ScriptResourceClient) should be notified when an empty script has been
  // loaded.
  V8TestingScope scope;

  // Finish the script without sending any data.
  Finish();
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());

  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_FALSE(source_code.Streamer());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_SmallScripts) {
  // Small scripts shouldn't be streamed.
  V8TestingScope scope;
  ScriptStreamer::SetSmallScriptThresholdForTesting(100);

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

  Finish();
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());

  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_FALSE(source_code.Streamer());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_ScriptsWithSmallFirstChunk) {
  // If a script is long enough, if should be streamed, even if the first data
  // chunk is small.
  V8TestingScope scope;
  ScriptStreamer::SetSmallScriptThresholdForTesting(100);

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

  Finish();

  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());
  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_TRUE(source_code.Streamer());
  v8::TryCatch try_catch(scope.GetIsolate());
  v8::Local<v8::Script> script;
  v8::ScriptCompiler::CompileOptions compile_options;
  V8CodeCache::ProduceCacheOptions produce_cache_options;
  v8::ScriptCompiler::NoCacheReason no_cache_reason;
  std::tie(compile_options, produce_cache_options, no_cache_reason) =
      V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault,
                                     source_code);
  EXPECT_TRUE(V8ScriptRunner::CompileScript(
                  scope.GetScriptState(), source_code,
                  SanitizeScriptErrors::kDoNotSanitize, compile_options,
                  no_cache_reason, ReferrerScriptInfo())
                  .ToLocal(&script));
  EXPECT_FALSE(try_catch.HasCaught());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_EncodingChanges) {
  // It's possible that the encoding of the Resource changes after we start
  // loading it.
  V8TestingScope scope;
  resource_->SetEncodingForTest("windows-1252");

  resource_->SetEncodingForTest("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(resource_client_->Finished());
  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_TRUE(source_code.Streamer());
  v8::TryCatch try_catch(scope.GetIsolate());
  v8::Local<v8::Script> script;
  v8::ScriptCompiler::CompileOptions compile_options;
  V8CodeCache::ProduceCacheOptions produce_cache_options;
  v8::ScriptCompiler::NoCacheReason no_cache_reason;
  std::tie(compile_options, produce_cache_options, no_cache_reason) =
      V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault,
                                     source_code);
  EXPECT_TRUE(V8ScriptRunner::CompileScript(
                  scope.GetScriptState(), source_code,
                  SanitizeScriptErrors::kDoNotSanitize, compile_options,
                  no_cache_reason, ReferrerScriptInfo())
                  .ToLocal(&script));
  EXPECT_FALSE(try_catch.HasCaught());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) {
  // Byte order marks should be removed before giving the data to V8. They
  // will also affect encoding detection.
  V8TestingScope scope;

  // This encoding is wrong on purpose.
  resource_->SetEncodingForTest("windows-1252");

  // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes
  // for \uc481.
  AppendData(
      "\xef\xbb\xbf function foo() { var foob\xec\x92\x81r = 13; return "
      "foob\xec\x92\x81r; } foo();");

  Finish();
  ProcessTasksUntilStreamingComplete();
  EXPECT_TRUE(resource_client_->Finished());
  ScriptSourceCode source_code = GetScriptSourceCode();
  EXPECT_TRUE(source_code.Streamer());
  v8::TryCatch try_catch(scope.GetIsolate());
  v8::Local<v8::Script> script;
  v8::ScriptCompiler::CompileOptions compile_options;
  V8CodeCache::ProduceCacheOptions produce_cache_options;
  v8::ScriptCompiler::NoCacheReason no_cache_reason;
  std::tie(compile_options, produce_cache_options, no_cache_reason) =
      V8CodeCache::GetCompileOptions(mojom::blink::V8CacheOptions::kDefault,
                                     source_code);
  EXPECT_TRUE(V8ScriptRunner::CompileScript(
                  scope.GetScriptState(), source_code,
                  SanitizeScriptErrors::kDoNotSanitize, compile_options,
                  no_cache_reason, ReferrerScriptInfo())
                  .ToLocal(&script));
  EXPECT_FALSE(try_catch.HasCaught());
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
// A test for crbug.com/711703. Should not crash.
TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) {
  V8TestingScope scope;

  EXPECT_FALSE(resource_client_->Finished());

  resource_ = nullptr;
  ThreadState::Current()->CollectAllGarbageForTesting(
      BlinkGC::kNoHeapPointersOnStack);
}

// TODO(crbug.com/939054): Tests are disabled due to flakiness caused by being
// currently unable to block and wait for the script streaming thread.
TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) {
  V8TestingScope scope;

  // Kick the streaming off.
  AppendData("function foo() {");
  AppendPadding();
  AppendData("}");
  Finish();
  ProcessTasksUntilStreamingComplete();

  // Should be done streaming by now.
  EXPECT_TRUE(resource_->HasStreamer());
  EXPECT_FALSE(resource_->HasRunningStreamer());

  ResourceRequest request(resource_->Url());
  resource_->SetRevalidatingRequest(request);

  // Now there shouldn't be a streamer at all, and the reason should be
  // "kRevalidate".
  EXPECT_FALSE(resource_->HasStreamer());
  EXPECT_EQ(resource_->NoStreamerReason(),
            ScriptStreamer::NotStreamingReason::kRevalidate);
}

}  // namespace

}  // namespace blink
