// Copyright 2017 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/browser/loader/detachable_resource_handler.h"

#include <string>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/browser/loader/mock_resource_loader.h"
#include "content/browser/loader/resource_controller.h"
#include "content/browser/loader/test_resource_handler.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_response.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace content {

namespace {

// Full response body.
const char kResponseBody[] = "Nifty response body.";
// Two separate reads allow for testing cancellation in the middle of one read,
// and between reads.
const char kFirstBodyRead[] = "Nifty";
const char kSecondBodyRead[] = " response body.";

enum class DetachPhase {
  DETACHED_FROM_CREATION,
  ON_WILL_START,
  REQUEST_REDIRECTED,
  ON_RESPONSE_STARTED,
  FIRST_ON_WILL_READ,
  FIRST_ON_READ_COMPLETED,
  SECOND_ON_WILL_READ,
  SECOND_ON_READ_COMPLETED,
  ON_READ_EOF,
  ON_RESPONSE_COMPLETED,
  NEVER_DETACH,
};

class DetachableResourceHandlerTest
    : public testing::TestWithParam<DetachPhase> {
 public:
  DetachableResourceHandlerTest()
      : request_(context_.CreateRequest(GURL("http://foo/"),
                                        net::DEFAULT_PRIORITY,
                                        nullptr,
                                        TRAFFIC_ANNOTATION_FOR_TESTS)) {
    ResourceRequestInfo::AllocateForTesting(request_.get(),
                                            RESOURCE_TYPE_MAIN_FRAME,
                                            nullptr,  // context
                                            0,        // render_process_id
                                            0,        // render_view_id
                                            0,        // render_frame_id
                                            true,     // is_main_frame
                                            false,    // parent_is_main_frame
                                            true,     // allow_download
                                            true,     // is_async
                                            PREVIEWS_OFF);  // previews_state

    std::unique_ptr<TestResourceHandler> test_handler;
    if (GetParam() != DetachPhase::DETACHED_FROM_CREATION) {
      test_handler = base::MakeUnique<TestResourceHandler>();
      test_handler_ = test_handler->GetWeakPtr();
    }
    // TODO(mmenke):  This file currently has no timeout tests. Should it?
    detachable_handler_ = base::MakeUnique<DetachableResourceHandler>(
        request_.get(), base::TimeDelta::FromMinutes(30),
        std::move(test_handler));
    mock_loader_ =
        base::MakeUnique<MockResourceLoader>(detachable_handler_.get());
  }

  // If the DetachableResourceHandler is supposed to detach the next handler at
  // |phase|, attempts to detach the request.
  void MaybeSyncDetachAtPhase(DetachPhase phase) {
    if (GetParam() == phase) {
      detachable_handler_->Detach();
      EXPECT_FALSE(test_handler_);
    }
  }

  // Returns true if the DetachableResourceHandler should have detached the next
  // handler at or before the specified phase.  Also checks that |test_handler_|
  // is nullptr iff the request should have been detached by the specified
  // phase.
  bool WasDetachedBy(DetachPhase phase) {
    if (GetParam() <= phase) {
      EXPECT_FALSE(test_handler_);
      return true;
    }
    EXPECT_TRUE(test_handler_);
    return false;
  }

  // If the DetachableResourceHandler is supposed to detach the next handler at
  // |phase|, attempts to detach the request. Expected to be called in sync
  // tests after the specified phase has started. Performs additional sanity
  // checks based on that assumption.
  void MaybeAsyncDetachAt(DetachPhase phase) {
    if (GetParam() < phase) {
      EXPECT_FALSE(test_handler_);
      EXPECT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
      return;
    }

    EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
              mock_loader_->status());

    if (GetParam() == phase) {
      detachable_handler_->Detach();
      EXPECT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
      EXPECT_FALSE(test_handler_);
      return;
    }

    test_handler_->Resume();
  }

 protected:
  TestBrowserThreadBundle thread_bundle_;
  net::TestURLRequestContext context_;
  std::unique_ptr<net::URLRequest> request_;

  base::WeakPtr<TestResourceHandler> test_handler_;

  std::unique_ptr<DetachableResourceHandler> detachable_handler_;
  std::unique_ptr<MockResourceLoader> mock_loader_;
};

// Tests where ResourceHandler completes synchronously. Handler is detached
// just before the phase indicated by the DetachPhase parameter.
TEST_P(DetachableResourceHandlerTest, Sync) {
  MaybeSyncDetachAtPhase(DetachPhase::ON_WILL_START);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnWillStart(request_->url()));
  if (!WasDetachedBy(DetachPhase::ON_WILL_START)) {
    EXPECT_EQ(1, test_handler_->on_will_start_called());
    EXPECT_EQ(0, test_handler_->on_request_redirected_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::REQUEST_REDIRECTED);
  ASSERT_EQ(
      MockResourceLoader::Status::IDLE,
      mock_loader_->OnRequestRedirected(
          net::RedirectInfo(), make_scoped_refptr(new ResourceResponse())));
  if (!WasDetachedBy(DetachPhase::REQUEST_REDIRECTED)) {
    EXPECT_EQ(1, test_handler_->on_request_redirected_called());
    EXPECT_EQ(0, test_handler_->on_response_started_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::ON_RESPONSE_STARTED);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnResponseStarted(
                make_scoped_refptr(new ResourceResponse())));
  if (!WasDetachedBy(DetachPhase::ON_RESPONSE_STARTED)) {
    EXPECT_EQ(1, test_handler_->on_request_redirected_called());
    EXPECT_EQ(1, test_handler_->on_response_started_called());
    EXPECT_EQ(0, test_handler_->on_will_read_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::FIRST_ON_WILL_READ);
  ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
  if (!WasDetachedBy(DetachPhase::FIRST_ON_WILL_READ)) {
    EXPECT_EQ(1, test_handler_->on_will_read_called());
    EXPECT_EQ(0, test_handler_->on_read_completed_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::FIRST_ON_READ_COMPLETED);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnReadCompleted(kFirstBodyRead));
  if (!WasDetachedBy(DetachPhase::FIRST_ON_READ_COMPLETED)) {
    EXPECT_EQ(1, test_handler_->on_read_completed_called());
    EXPECT_EQ(kFirstBodyRead, test_handler_->body());
  }

  MaybeSyncDetachAtPhase(DetachPhase::SECOND_ON_WILL_READ);
  ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
  if (!WasDetachedBy(DetachPhase::SECOND_ON_WILL_READ)) {
    EXPECT_EQ(2, test_handler_->on_will_read_called());
    EXPECT_EQ(1, test_handler_->on_read_completed_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::SECOND_ON_READ_COMPLETED);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnReadCompleted(kSecondBodyRead));
  if (!WasDetachedBy(DetachPhase::SECOND_ON_READ_COMPLETED)) {
    EXPECT_EQ(2, test_handler_->on_will_read_called());
    EXPECT_EQ(2, test_handler_->on_read_completed_called());
    EXPECT_EQ(kResponseBody, test_handler_->body());
  }

  ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
  if (!WasDetachedBy(DetachPhase::SECOND_ON_READ_COMPLETED)) {
    EXPECT_EQ(3, test_handler_->on_will_read_called());
    EXPECT_EQ(2, test_handler_->on_read_completed_called());
    EXPECT_EQ(0, test_handler_->on_response_completed_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::ON_READ_EOF);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnReadCompleted(""));
  if (!WasDetachedBy(DetachPhase::ON_READ_EOF)) {
    EXPECT_EQ(3, test_handler_->on_read_completed_called());
    EXPECT_EQ(1, test_handler_->on_read_eof_called());
    EXPECT_EQ(0, test_handler_->on_response_completed_called());
  }

  MaybeSyncDetachAtPhase(DetachPhase::ON_RESPONSE_COMPLETED);
  ASSERT_EQ(MockResourceLoader::Status::IDLE,
            mock_loader_->OnResponseCompleted(
                net::URLRequestStatus::FromError(net::OK)));
  if (!WasDetachedBy(DetachPhase::ON_RESPONSE_COMPLETED)) {
    EXPECT_EQ(1, test_handler_->on_response_completed_called());
    EXPECT_EQ(kResponseBody, test_handler_->body());
  }
}

// Tests where ResourceHandler completes asynchronously. Handler is detached
// during the phase indicated by the DetachPhase parameter. Async cases where
// the handler is detached between phases are similar enough to the sync tests
// that they wouldn't provide meaningfully better test coverage.
//
// Before the handler is detached, all calls complete asynchronously.
// Afterwards, they all complete synchronously.
TEST_P(DetachableResourceHandlerTest, Async) {
  if (GetParam() != DetachPhase::DETACHED_FROM_CREATION) {
    test_handler_->set_defer_on_will_start(true);
    test_handler_->set_defer_on_request_redirected(true);
    test_handler_->set_defer_on_response_started(true);
    test_handler_->set_defer_on_will_read(true);
    test_handler_->set_defer_on_read_completed(true);
    test_handler_->set_defer_on_read_eof(true);
    // Note:  Can't set |defer_on_response_completed|, since the
    // DetachableResourceHandler DCHECKs when the next handler tries to defer
    // the ERR_ABORTED message it sends downstream.
  }

  mock_loader_->OnWillStart(request_->url());
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_will_start_called());
    EXPECT_EQ(0, test_handler_->on_request_redirected_called());
  }
  MaybeAsyncDetachAt(DetachPhase::ON_WILL_START);

  mock_loader_->OnRequestRedirected(net::RedirectInfo(),
                                    make_scoped_refptr(new ResourceResponse()));
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_request_redirected_called());
    EXPECT_EQ(0, test_handler_->on_response_started_called());
  }
  MaybeAsyncDetachAt(DetachPhase::REQUEST_REDIRECTED);

  mock_loader_->OnResponseStarted(make_scoped_refptr(new ResourceResponse()));
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_request_redirected_called());
    EXPECT_EQ(1, test_handler_->on_response_started_called());
    EXPECT_EQ(0, test_handler_->on_will_read_called());
  }
  MaybeAsyncDetachAt(DetachPhase::ON_RESPONSE_STARTED);

  mock_loader_->OnWillRead();
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_will_read_called());
    EXPECT_EQ(0, test_handler_->on_read_completed_called());
  }
  MaybeAsyncDetachAt(DetachPhase::FIRST_ON_WILL_READ);

  mock_loader_->OnReadCompleted(kFirstBodyRead);
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_read_completed_called());
    EXPECT_EQ(kFirstBodyRead, test_handler_->body());
  }
  MaybeAsyncDetachAt(DetachPhase::FIRST_ON_READ_COMPLETED);

  if (test_handler_)
    test_handler_->set_defer_on_will_read(true);
  mock_loader_->OnWillRead();
  if (test_handler_) {
    EXPECT_EQ(2, test_handler_->on_will_read_called());
    EXPECT_EQ(1, test_handler_->on_read_completed_called());
  }
  MaybeAsyncDetachAt(DetachPhase::SECOND_ON_WILL_READ);

  if (test_handler_)
    test_handler_->set_defer_on_read_completed(true);
  mock_loader_->OnReadCompleted(kSecondBodyRead);
  if (test_handler_) {
    EXPECT_EQ(2, test_handler_->on_will_read_called());
    EXPECT_EQ(2, test_handler_->on_read_completed_called());
    EXPECT_EQ(kResponseBody, test_handler_->body());
  }
  MaybeAsyncDetachAt(DetachPhase::SECOND_ON_READ_COMPLETED);

  // Test doesn't check detaching on the third OnWillRead call.
  ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
  if (GetParam() > DetachPhase::SECOND_ON_READ_COMPLETED) {
    EXPECT_EQ(3, test_handler_->on_will_read_called());
    EXPECT_EQ(2, test_handler_->on_read_completed_called());
    EXPECT_EQ(0, test_handler_->on_response_completed_called());
  } else {
    EXPECT_FALSE(test_handler_);
  }

  if (test_handler_)
    test_handler_->set_defer_on_read_completed(true);
  mock_loader_->OnReadCompleted("");
  if (test_handler_) {
    EXPECT_EQ(3, test_handler_->on_read_completed_called());
    EXPECT_EQ(1, test_handler_->on_read_eof_called());
    EXPECT_EQ(0, test_handler_->on_response_completed_called());
  }
  MaybeAsyncDetachAt(DetachPhase::ON_READ_EOF);

  if (test_handler_)
    test_handler_->set_defer_on_response_completed(true);
  mock_loader_->OnResponseCompleted(net::URLRequestStatus::FromError(net::OK));
  if (test_handler_) {
    EXPECT_EQ(1, test_handler_->on_response_completed_called());
    EXPECT_EQ(kResponseBody, test_handler_->body());
  }
  MaybeAsyncDetachAt(DetachPhase::ON_RESPONSE_COMPLETED);
}

INSTANTIATE_TEST_CASE_P(/* No prefix needed*/,
                        DetachableResourceHandlerTest,
                        testing::Values(DetachPhase::DETACHED_FROM_CREATION,
                                        DetachPhase::ON_WILL_START,
                                        DetachPhase::REQUEST_REDIRECTED,
                                        DetachPhase::ON_RESPONSE_STARTED,
                                        DetachPhase::FIRST_ON_WILL_READ,
                                        DetachPhase::FIRST_ON_READ_COMPLETED,
                                        DetachPhase::SECOND_ON_WILL_READ,
                                        DetachPhase::SECOND_ON_READ_COMPLETED,
                                        DetachPhase::ON_READ_EOF,
                                        DetachPhase::ON_RESPONSE_COMPLETED,
                                        DetachPhase::NEVER_DETACH));

}  // namespace

}  // namespace content
