// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/testing/embedded_test_server_handlers.h"

#include <utility>

#include "base/functional/bind.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "url/gurl.h"

namespace testing {

const char kTestFormPage[] = "ios.testing.HandleForm";
const char kTestFormFieldValue[] = "test-value";
const char kTestDownloadMimeType[] = "application/vnd.test";

namespace {
// Extracts and escapes url spec from the query.
std::string ExtractUlrSpecFromQuery(
    const net::test_server::HttpRequest& request) {
  GURL request_url = request.GetURL();
  std::string spec = base::UnescapeBinaryURLComponent(request_url.query());

  // Escape the URL spec.
  GURL url(spec);
  return url.is_valid() ? base::EscapeForHTML(url.spec()) : spec;
}

// A HttpResponse that responds with |length| zeroes and kTestDownloadMimeType
// MIME Type.
class DownloadResponse : public net::test_server::BasicHttpResponse {
 public:
  DownloadResponse(int length) : length_(length) {}

  DownloadResponse(const DownloadResponse&) = delete;
  DownloadResponse& operator=(const DownloadResponse&) = delete;

  void SendResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override {
    base::StringPairs headers = {
        {"content-type", kTestDownloadMimeType},
        {"content-length", base::StringPrintf("%d", length_)}};

    delegate->SendResponseHeaders(net::HTTP_OK, "OK", headers);
    Send(delegate, length_);
  }

 private:
  // Sends "0" |count| times using 1KB blocks. Using blocks with smaller size is
  // performance inefficient and can cause unnecessary delays especially when
  // multiple tests run in parallel on a single machine.
  static void Send(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate,
      int count) {
    if (!count) {
      if (delegate) {
        delegate->FinishResponse();
      }
      return;
    }
    int block_size = std::min(count, 1000);
    std::string content_block(block_size, 0);
    auto next_send =
        base::BindOnce(&DownloadResponse::Send, delegate, count - block_size);

    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&net::test_server::HttpResponseDelegate::SendContents,
                       delegate, content_block, std::move(next_send)),
        base::Milliseconds(100));
  }

  int length_ = 0;
};

// A slow response that would take several hours to finish. This is useful for
// testing scenarios where a load is interrupted after it starts but before it
// finishes.
class SlowResponse : public net::test_server::BasicHttpResponse {
 public:
  SlowResponse() = default;

  SlowResponse(const SlowResponse&) = delete;
  SlowResponse& operator=(const SlowResponse&) = delete;

  void SendResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override {
    delegate_ = delegate;
    delegate_->SendResponseHeaders(
        net::HTTP_OK, "OK",
        {{"Content-Length",
          base::NumberToString(kilobytes_left_to_send_ * 1024)},
         {"Content-Type", "text/plain"}});
    SendKilobyte();
  }

 private:
  void SendKilobyte() {
    if (kilobytes_left_to_send_ == 0) {
      delegate_->FinishResponse();
      return;
    }

    DCHECK_GT(kilobytes_left_to_send_, 0);
    kilobytes_left_to_send_--;

    delegate_->SendContents(
        std::string(1024, 'a'),
        base::BindOnce(&SlowResponse::SendKilobyteAfterDelay,
                       weak_factory_.GetWeakPtr()));
  }

  void SendKilobyteAfterDelay() {
    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&SlowResponse::SendKilobyte, weak_factory_.GetWeakPtr()),
        delay_between_kilobytes_);
  }

  base::WeakPtrFactory<SlowResponse> weak_factory_{this};
  base::WeakPtr<net::test_server::HttpResponseDelegate> delegate_ = nullptr;
  int kilobytes_left_to_send_ = 100000;
  base::TimeDelta delay_between_kilobytes_ = base::Seconds(1);
};

}  // namespace

std::unique_ptr<net::test_server::HttpResponse> HandleIFrame(
    const net::test_server::HttpRequest& request) {
  auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  http_response->set_content_type("text/html");
  http_response->set_content(
      base::StringPrintf("<html><head></head><body><iframe "
                         "src='%s'></iframe>Main frame text</body></html>",
                         ExtractUlrSpecFromQuery(request).c_str()));
  return std::move(http_response);
}

// Returns a page with |html|.
std::unique_ptr<net::test_server::HttpResponse> HandlePageWithHtml(
    const std::string& html,
    const net::test_server::HttpRequest& request) {
  auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  http_response->set_content_type("text/html");
  http_response->set_content(html);
  return std::move(http_response);
}

std::unique_ptr<net::test_server::HttpResponse> HandlePageWithContents(
    const net::test_server::HttpRequest& request) {
  auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  http_response->set_content_type("text/html");
  http_response->set_content(request.GetURL().GetQuery());
  return std::move(http_response);
}

std::unique_ptr<net::test_server::HttpResponse> HandleEchoQueryOrCloseSocket(
    const bool& responds_with_content,
    const net::test_server::HttpRequest& request) {
  if (!responds_with_content) {
    return std::make_unique<net::test_server::RawHttpResponse>(
        /*headers=*/"", /*contents=*/"");
  }
  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
  response->set_content_type("text/html");
  response->set_content(request.GetURL().GetQuery());
  response->AddCustomHeader("Cache-Control", "no-store");
  return std::move(response);
}

std::unique_ptr<net::test_server::HttpResponse> HandleForm(
    const net::test_server::HttpRequest& request) {
  std::string form_action = ExtractUlrSpecFromQuery(request);
  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
  response->set_content_type("text/html");
  response->set_content(base::StringPrintf(
      "<form method='post' id='form' action='%s'>"
      "  <input type='text' name='test-name' value='%s'>"
      "</form>"
      "%s",
      form_action.c_str(), kTestFormFieldValue, kTestFormPage));

  return std::move(response);
}

std::unique_ptr<net::test_server::HttpResponse> HandleDownload(
    const net::test_server::HttpRequest& request) {
  int length = 0;
  if (!base::StringToInt(request.GetURL().GetQuery(), &length)) {
    length = 1;
  }

  return std::make_unique<DownloadResponse>(length);
}

std::unique_ptr<net::test_server::HttpResponse> HandleSlow(
    const net::test_server::HttpRequest& request) {
  return std::make_unique<SlowResponse>();
}

}  // namespace testing
