// Copyright 2018 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 "content/renderer/loader/sync_load_context.h"
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread.h"
#include "content/renderer/loader/sync_load_response.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

class TestSharedURLLoaderFactory : public network::TestURLLoaderFactory,
                                   public network::SharedURLLoaderFactory {
 public:
  // mojom::URLLoaderFactory implementation.
  void CreateLoaderAndStart(
      mojo::PendingReceiver<network::mojom::URLLoader> receiver,
      int32_t routing_id,
      int32_t request_id,
      uint32_t options,
      const network::ResourceRequest& url_request,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client,
      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
      override {
    network::TestURLLoaderFactory::CreateLoaderAndStart(
        std::move(receiver), routing_id, request_id, options, url_request,
        std::move(client), traffic_annotation);
  }

  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>) override {
    NOTREACHED();
  }

  std::unique_ptr<network::PendingSharedURLLoaderFactory> Clone() override {
    NOTREACHED();
    return nullptr;
  }

 private:
  friend class base::RefCounted<TestSharedURLLoaderFactory>;
  ~TestSharedURLLoaderFactory() override = default;
};

class MockPendingSharedURLLoaderFactory
    : public network::PendingSharedURLLoaderFactory {
 public:
  explicit MockPendingSharedURLLoaderFactory()
      : factory_(base::MakeRefCounted<TestSharedURLLoaderFactory>()) {}

  scoped_refptr<TestSharedURLLoaderFactory> factory() const { return factory_; }

 protected:
  scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override {
    return factory_;
  }

  scoped_refptr<TestSharedURLLoaderFactory> factory_;
};

class MockResourceDispatcher : public ResourceDispatcher {
 public:
  int CreatePendingRequest(std::unique_ptr<RequestPeer> peer) {
    peers_.push_back(std::move(peer));
    return peers_.size() - 1;
  }

  bool RemovePendingRequest(
      int request_id,
      scoped_refptr<base::SingleThreadTaskRunner>) override {
    if (request_id < 0 || static_cast<int>(peers_.size()) <= request_id)
      return false;
    peers_[request_id].reset();
    return true;
  }

 private:
  std::vector<std::unique_ptr<RequestPeer>> peers_;
};

}  // namespace

class SyncLoadContextTest : public testing::Test {
 public:
  SyncLoadContextTest() : loading_thread_("loading thread") {}

  void SetUp() override {
    ASSERT_TRUE(loading_thread_.StartAndWaitForTesting());
  }

  void StartAsyncWithWaitableEventOnLoadingThread(
      std::unique_ptr<network::ResourceRequest> request,
      std::unique_ptr<network::PendingSharedURLLoaderFactory> pending_factory,
      SyncLoadResponse* out_response,
      base::WaitableEvent* redirect_or_response_event) {
    loading_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(
            &SyncLoadContext::StartAsyncWithWaitableEvent, std::move(request),
            MSG_ROUTING_NONE, loading_thread_.task_runner(),
            TRAFFIC_ANNOTATION_FOR_TESTS, 0 /* loader_options */,
            std::move(pending_factory),
            std::vector<std::unique_ptr<blink::URLLoaderThrottle>>(),
            out_response, redirect_or_response_event,
            nullptr /* terminate_sync_load_event */,
            base::TimeDelta::FromSeconds(60) /* timeout */,
            mojo::NullRemote() /* download_to_blob_registry */,
            std::vector<std::string>() /* cors_exempt_header_list */));
  }

  static void RunSyncLoadContextViaDataPipe(
      network::ResourceRequest* request,
      SyncLoadResponse* response,
      std::string expected_data,
      base::WaitableEvent* redirect_or_response_event,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
    DCHECK(task_runner->BelongsToCurrentThread());
    auto* context = new SyncLoadContext(
        request, std::make_unique<MockPendingSharedURLLoaderFactory>(),
        response, redirect_or_response_event,
        nullptr /* terminate_sync_load_event */,
        base::TimeDelta::FromSeconds(60) /* timeout */,
        mojo::NullRemote() /* download_to_blob_registry */, task_runner,
        std::vector<std::string>() /* cors_exempt_header_list */);

    // Override |resource_dispatcher_| for testing.
    auto dispatcher = std::make_unique<MockResourceDispatcher>();
    context->request_id_ =
        dispatcher->CreatePendingRequest(base::WrapUnique(context));
    context->resource_dispatcher_ = std::move(dispatcher);

    // Simulate the response.
    context->OnReceivedResponse(network::mojom::URLResponseHead::New());
    mojo::ScopedDataPipeProducerHandle producer_handle;
    mojo::ScopedDataPipeConsumerHandle consumer_handle;
    EXPECT_EQ(MOJO_RESULT_OK,
              mojo::CreateDataPipe(nullptr /* options */, &producer_handle,
                                   &consumer_handle));
    context->OnStartLoadingResponseBody(std::move(consumer_handle));
    context->OnCompletedRequest(network::URLLoaderCompletionStatus(net::OK));

    mojo::BlockingCopyFromString(expected_data, producer_handle);
  }

  base::Thread loading_thread_;
};

TEST_F(SyncLoadContextTest, StartAsyncWithWaitableEvent) {
  GURL expected_url = GURL("https://example.com");
  std::string expected_data = "foobarbaz";

  // Create and exercise SyncLoadContext on the |loading_thread_|.
  auto request = std::make_unique<network::ResourceRequest>();
  request->url = expected_url;
  auto pending_factory = std::make_unique<MockPendingSharedURLLoaderFactory>();
  pending_factory->factory()->AddResponse(expected_url.spec(), expected_data);
  SyncLoadResponse response;
  base::WaitableEvent redirect_or_response_event(
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  StartAsyncWithWaitableEventOnLoadingThread(
      std::move(request), std::move(pending_factory), &response,
      &redirect_or_response_event);

  // Wait until the response is received.
  redirect_or_response_event.Wait();

  // Check if |response| is set properly after the WaitableEvent fires.
  EXPECT_EQ(net::OK, response.error_code);
  EXPECT_EQ(expected_data, response.data);
}

TEST_F(SyncLoadContextTest, ResponseBodyViaDataPipe) {
  GURL expected_url = GURL("https://example.com");
  std::string expected_data = "foobarbaz";

  // Create and exercise SyncLoadContext on the |loading_thread_|.
  auto request = std::make_unique<network::ResourceRequest>();
  request->url = expected_url;
  SyncLoadResponse response;
  base::WaitableEvent redirect_or_response_event(
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  loading_thread_.task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&SyncLoadContextTest::RunSyncLoadContextViaDataPipe,
                     request.get(), &response, expected_data,
                     &redirect_or_response_event,
                     loading_thread_.task_runner()));

  // Wait until the response is received.
  redirect_or_response_event.Wait();

  // Check if |response| is set properly after the WaitableEvent fires.
  EXPECT_EQ(net::OK, response.error_code);
  EXPECT_EQ(expected_data, response.data);
}

}  // namespace content
