// Copyright 2016 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/test_resource_handler.h"

#include "base/logging.h"
#include "content/browser/loader/resource_controller.h"
#include "services/network/public/cpp/resource_response.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

class ScopedCallDepthTracker {
 public:
  explicit ScopedCallDepthTracker(int* call_depth) : call_depth_(call_depth) {
    EXPECT_EQ(0, *call_depth_);
    (*call_depth_)++;
  }

  ~ScopedCallDepthTracker() {
    EXPECT_EQ(1, *call_depth_);
    (*call_depth_)--;
  }

 private:
  int* const call_depth_;

  DISALLOW_COPY_AND_ASSIGN(ScopedCallDepthTracker);
};

}  // namespace

TestResourceHandler::TestResourceHandler(net::URLRequestStatus* request_status,
                                         std::string* body)
    : ResourceHandler(nullptr),
      request_status_ptr_(request_status),
      body_ptr_(body),
      deferred_run_loop_(new base::RunLoop()),
      weak_ptr_factory_(this) {
  SetBufferSize(2048);
}

TestResourceHandler::TestResourceHandler()
    : TestResourceHandler(nullptr, nullptr) {}

TestResourceHandler::~TestResourceHandler() {}

void TestResourceHandler::OnRequestRedirected(
    const net::RedirectInfo& redirect_info,
    network::ResourceResponse* response,
    std::unique_ptr<ResourceController> controller) {
  EXPECT_FALSE(canceled_);
  EXPECT_EQ(1, on_will_start_called_);
  EXPECT_EQ(0, on_response_started_called_);
  EXPECT_EQ(0, on_response_completed_called_);
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  ++on_request_redirected_called_;

  if (!on_request_redirected_result_) {
    canceled_ = true;
    controller->Cancel();
    return;
  }

  if (defer_on_request_redirected_) {
    defer_on_request_redirected_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  controller->Resume();
}

void TestResourceHandler::OnResponseStarted(
    network::ResourceResponse* response,
    std::unique_ptr<ResourceController> controller) {
  EXPECT_FALSE(canceled_);
  EXPECT_EQ(1, on_will_start_called_);
  EXPECT_EQ(0, on_response_started_called_);
  EXPECT_EQ(0, on_response_completed_called_);
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  ++on_response_started_called_;

  EXPECT_FALSE(resource_response_);
  resource_response_ = response;

  response_started_run_loop_.Quit();

  if (!on_response_started_result_) {
    canceled_ = true;
    controller->Cancel();
    return;
  }

  if (!on_request_redirected_result_) {
    controller->Cancel();
    return;
  }

  if (defer_on_response_started_) {
    defer_on_response_started_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  controller->Resume();
}

void TestResourceHandler::OnWillStart(
    const GURL& url,
    std::unique_ptr<ResourceController> controller) {
  EXPECT_FALSE(canceled_);
  EXPECT_EQ(0, on_response_started_called_);
  EXPECT_EQ(0, on_will_start_called_);
  EXPECT_EQ(0, on_response_completed_called_);
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  ++on_will_start_called_;

  start_url_ = url;

  if (!on_will_start_result_) {
    canceled_ = true;
    controller->Cancel();
    return;
  }

  if (defer_on_will_start_) {
    defer_on_will_start_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  controller->Resume();
}

void TestResourceHandler::OnWillRead(
    scoped_refptr<net::IOBuffer>* buf,
    int* buf_size,
    std::unique_ptr<ResourceController> controller) {
  EXPECT_FALSE(canceled_);
  EXPECT_EQ(0, on_response_completed_called_);
  // Only create a ScopedCallDepthTracker if not called re-entrantly, as
  // OnWillRead may be called synchronously in response to a Resume(), but
  // nothing may be called synchronously in response to the OnWillRead call.
  std::unique_ptr<ScopedCallDepthTracker> call_depth_tracker;
  if (call_depth_ == 0)
    call_depth_tracker = std::make_unique<ScopedCallDepthTracker>(&call_depth_);

  ++on_will_read_called_;

  if (!on_will_read_result_) {
    canceled_ = true;
    controller->Cancel();
    return;
  }

  if (defer_on_will_read_) {
    parent_read_buffer_ = buf;
    parent_read_buffer_size_ = buf_size;
    defer_on_will_read_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  *buf = buffer_;
  *buf_size = buffer_size_;
  controller->Resume();
}

void TestResourceHandler::OnReadCompleted(
    int bytes_read,
    std::unique_ptr<ResourceController> controller) {
  EXPECT_FALSE(canceled_);
  EXPECT_EQ(1, on_will_start_called_);
  EXPECT_EQ(1, on_response_started_called_);
  EXPECT_EQ(0, on_response_completed_called_);
  EXPECT_EQ(0, on_read_eof_called_);
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  ++on_read_completed_called_;
  EXPECT_EQ(on_read_completed_called_, on_will_read_called_);
  if (bytes_read == 0)
    ++on_read_eof_called_;

  EXPECT_LE(static_cast<size_t>(bytes_read), buffer_size_);
  if (body_ptr_)
    body_ptr_->append(buffer_->data(), bytes_read);
  body_.append(buffer_->data(), bytes_read);

  if (!on_read_completed_result_ || (!on_read_eof_result_ && bytes_read == 0)) {
    canceled_ = true;
    controller->Cancel();
    return;
  }

  if (defer_on_read_completed_ || (bytes_read == 0 && defer_on_read_eof_)) {
    defer_on_read_completed_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  controller->Resume();
}

void TestResourceHandler::OnResponseCompleted(
    const net::URLRequestStatus& status,
    std::unique_ptr<ResourceController> controller) {
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  // These may be non-NULL if there was an out-of-band cancel.
  parent_read_buffer_ = nullptr;
  parent_read_buffer_size_ = nullptr;

  EXPECT_EQ(0, on_response_completed_called_);
  if (status.is_success() && expect_eof_read_)
    EXPECT_EQ(1, on_read_eof_called_);

  ++on_response_completed_called_;

  if (request_status_ptr_)
    *request_status_ptr_ = status;
  final_status_ = status;

  // Consider response completed.  Even if deferring, the TestResourceHandler
  // won't be called again.
  response_complete_run_loop_.Quit();

  if (defer_on_response_completed_) {
    defer_on_response_completed_ = false;
    HoldController(std::move(controller));
    deferred_run_loop_->Quit();
    return;
  }

  controller->Resume();
}

void TestResourceHandler::Resume() {
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);

  if (parent_read_buffer_) {
    *parent_read_buffer_ = buffer_;
    *parent_read_buffer_size_ = buffer_size_;
    parent_read_buffer_ = nullptr;
    parent_read_buffer_size_ = nullptr;
    memset(buffer_->data(), '\0', buffer_size_);
  }

  ResourceHandler::Resume();
}

void TestResourceHandler::CancelWithError(net::Error net_error) {
  ScopedCallDepthTracker call_depth_tracker(&call_depth_);
  canceled_ = true;

  // Don't want to populate these after a cancel.
  parent_read_buffer_ = nullptr;
  parent_read_buffer_size_ = nullptr;

  ResourceHandler::CancelWithError(net_error);
}

void TestResourceHandler::SetBufferSize(int buffer_size) {
  buffer_ = base::MakeRefCounted<net::IOBuffer>(buffer_size);
  buffer_size_ = buffer_size;
  memset(buffer_->data(), '\0', buffer_size);
}

void TestResourceHandler::WaitUntilDeferred() {
  deferred_run_loop_->Run();
  deferred_run_loop_.reset(new base::RunLoop());
}

void TestResourceHandler::WaitUntilResponseStarted() {
  response_started_run_loop_.Run();
}

void TestResourceHandler::WaitUntilResponseComplete() {
  response_complete_run_loop_.Run();
}

base::WeakPtr<TestResourceHandler> TestResourceHandler::GetWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // namespace content
