// 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 "services/network/test/test_url_loader_factory.h"

#include "base/logging.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_request_body.h"

namespace network {

TestURLLoaderFactory::PendingRequest::PendingRequest() = default;
TestURLLoaderFactory::PendingRequest::~PendingRequest() = default;

TestURLLoaderFactory::PendingRequest::PendingRequest(PendingRequest&& other) =
    default;
TestURLLoaderFactory::PendingRequest& TestURLLoaderFactory::PendingRequest::
operator=(PendingRequest&& other) = default;

TestURLLoaderFactory::Response::Response() = default;
TestURLLoaderFactory::Response::~Response() = default;
TestURLLoaderFactory::Response::Response(const Response&) = default;

TestURLLoaderFactory::TestURLLoaderFactory() {}

TestURLLoaderFactory::~TestURLLoaderFactory() {}

void TestURLLoaderFactory::AddResponse(const GURL& url,
                                       const ResourceResponseHead& head,
                                       const std::string& content,
                                       const URLLoaderCompletionStatus& status,
                                       const Redirects& redirects) {
  Response response;
  response.url = url;
  response.redirects = redirects;
  response.head = head;
  response.content = content;
  response.status = status;
  responses_[url] = response;

  for (auto it = pending_requests_.begin(); it != pending_requests_.end();) {
    if (CreateLoaderAndStartInternal(it->request.url, it->client.get())) {
      it = pending_requests_.erase(it);
    } else {
      ++it;
    }
  }
}

void TestURLLoaderFactory::AddResponse(const std::string& url,
                                       const std::string& content,
                                       net::HttpStatusCode http_status) {
  ResourceResponseHead head = CreateResourceResponseHead(http_status);
  head.mime_type = "text/html";
  URLLoaderCompletionStatus status;
  status.decoded_body_length = content.size();
  AddResponse(GURL(url), head, content, status);
}

bool TestURLLoaderFactory::IsPending(const std::string& url,
                                     int* load_flags_out) {
  base::RunLoop().RunUntilIdle();
  for (const auto& candidate : pending_requests_) {
    if (candidate.request.url == url) {
      if (load_flags_out)
        *load_flags_out = candidate.request.load_flags;
      return !candidate.client.encountered_error();
    }
  }
  return false;
}

int TestURLLoaderFactory::NumPending() {
  int pending = 0;
  base::RunLoop().RunUntilIdle();
  for (const auto& candidate : pending_requests_) {
    if (!candidate.client.encountered_error())
      ++pending;
  }
  return pending;
}

void TestURLLoaderFactory::ClearResponses() {
  responses_.clear();
}

void TestURLLoaderFactory::SetInterceptor(const Interceptor& interceptor) {
  interceptor_ = interceptor;
}

void TestURLLoaderFactory::CreateLoaderAndStart(
    mojom::URLLoaderRequest request,
    int32_t routing_id,
    int32_t request_id,
    uint32_t options,
    const ResourceRequest& url_request,
    mojom::URLLoaderClientPtr client,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
  if (interceptor_)
    interceptor_.Run(url_request);

  if (CreateLoaderAndStartInternal(url_request.url, client.get()))
    return;

  PendingRequest pending_request;
  pending_request.client = std::move(client);
  pending_request.request = url_request;
  pending_requests_.push_back(std::move(pending_request));
}

void TestURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

bool TestURLLoaderFactory::CreateLoaderAndStartInternal(
    const GURL& url,
    mojom::URLLoaderClient* client) {
  auto it = responses_.find(url);
  if (it == responses_.end())
    return false;

  SimulateResponseImpl(client, it->second.redirects, it->second.head,
                       it->second.content, it->second.status);
  return true;
}

// static
void TestURLLoaderFactory::SimulateResponse(
    TestURLLoaderFactory::PendingRequest request,
    std::string content,
    int net_error,
    net::HttpStatusCode http_status) {
  network::URLLoaderCompletionStatus status(net_error);
  ResourceResponseHead head = CreateResourceResponseHead(http_status);
  status.decoded_body_length = content.size();
  SimulateResponseImpl(request.client.get(), TestURLLoaderFactory::Redirects(),
                       head, content, status);
  base::RunLoop().RunUntilIdle();
}

// static
ResourceResponseHead TestURLLoaderFactory::CreateResourceResponseHead(
    net::HttpStatusCode http_status) {
  ResourceResponseHead head;
  std::string headers(base::StringPrintf(
      "HTTP/1.1 %d %s\nContent-type: text/html\n\n",
      static_cast<int>(http_status), net::GetHttpReasonPhrase(http_status)));
  head.headers = new net::HttpResponseHeaders(
      net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
  return head;
}

// static
void TestURLLoaderFactory::SimulateResponseImpl(
    mojom::URLLoaderClient* client,
    TestURLLoaderFactory::Redirects redirects,
    ResourceResponseHead head,
    std::string content,
    URLLoaderCompletionStatus status) {
  for (const auto& redirect : redirects)
    client->OnReceiveRedirect(redirect.first, redirect.second);

  if (status.error_code == net::OK) {
    client->OnReceiveResponse(head);
    mojo::DataPipe data_pipe(content.size());
    uint32_t bytes_written = content.size();
    CHECK_EQ(MOJO_RESULT_OK, data_pipe.producer_handle->WriteData(
                                 content.data(), &bytes_written,
                                 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
    client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
  }
  client->OnComplete(status);
}

}  // namespace network
