// Copyright 2015 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 "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "mojo/common/data_pipe_utils.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/application_test_base.h"
#include "mojo/public/cpp/system/macros.h"
#include "mojo/services/http_server/public/cpp/http_server_util.h"
#include "mojo/services/http_server/public/interfaces/http_server.mojom.h"
#include "mojo/services/http_server/public/interfaces/http_server_factory.mojom.h"
#include "mojo/services/network/public/interfaces/net_address.mojom.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "mojo/services/network/public/interfaces/url_loader.mojom.h"

namespace http_server {

namespace {
void WriteMessageToDataPipe(
    const std::string message,
    mojo::ScopedDataPipeConsumerHandle* data_pipe_consumer) {
  mojo::ScopedDataPipeProducerHandle producer_handle_;
  MojoCreateDataPipeOptions options = {sizeof(MojoCreateDataPipeOptions),
                                       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
                                       1,
                                       message.size()};

  MojoResult result =
      CreateDataPipe(&options, &producer_handle_, data_pipe_consumer);
  ASSERT_EQ(MOJO_RESULT_OK, result);

  uint32_t bytes = message.size();
  result = WriteDataRaw(producer_handle_.get(), message.data(), &bytes,
                        MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
  ASSERT_EQ(result, MOJO_RESULT_OK);
  ASSERT_EQ(message.size(), bytes);
}

const char* kExampleMessage = "Hello, world!";
}  // namespace

// Test handler that responds to all requests with the status OK and
// kExampleMessage.
class GetHandler : public http_server::HttpHandler {
 public:
  GetHandler(mojo::InterfaceRequest<HttpHandler> request)
      : binding_(this, request.Pass()) {}
  ~GetHandler() override {}

  bool WaitForIncomingMethodCall() {
    return binding_.WaitForIncomingMethodCall();
  }

 private:
  // http_server::HttpHandler:
  void HandleRequest(http_server::HttpRequestPtr request,
                     const mojo::Callback<void(http_server::HttpResponsePtr)>&
                         callback) override {
    callback.Run(http_server::CreateHttpResponse(200, kExampleMessage));
  }

  mojo::Binding<http_server::HttpHandler> binding_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(GetHandler);
};

// Test handler that responds to POST requests with the status OK and message
// read from the payload of the request.
class PostHandler : public http_server::HttpHandler {
 public:
  PostHandler(mojo::InterfaceRequest<HttpHandler> request)
      : binding_(this, request.Pass()) {}
  ~PostHandler() override {}

  bool WaitForIncomingMethodCall() {
    return binding_.WaitForIncomingMethodCall();
  }

 private:
  // http_server::HttpHandler:
  void HandleRequest(http_server::HttpRequestPtr request,
                     const mojo::Callback<void(http_server::HttpResponsePtr)>&
                         callback) override {
    DCHECK_EQ("POST", request->method);
    std::string message;
    mojo::common::BlockingCopyToString(request->body.Pass(), &message);
    callback.Run(http_server::CreateHttpResponse(200, message));
  }

  mojo::Binding<http_server::HttpHandler> binding_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(PostHandler);
};

class HttpServerApplicationTest : public mojo::test::ApplicationTestBase {
 public:
  HttpServerApplicationTest() : ApplicationTestBase() {}
  ~HttpServerApplicationTest() override {}

 protected:
  // ApplicationTestBase:
  void SetUp() override {
    ApplicationTestBase::SetUp();

    application_impl()->ConnectToService("mojo:http_server",
                                         &http_server_factory_);
    application_impl()->ConnectToService("mojo:network_service",
                                         &network_service_);
  }

  http_server::HttpServerPtr CreateHttpServer();

  http_server::HttpServerFactoryPtr http_server_factory_;
  mojo::NetworkServicePtr network_service_;

 private:
  MOJO_DISALLOW_COPY_AND_ASSIGN(HttpServerApplicationTest);
};

http_server::HttpServerPtr HttpServerApplicationTest::CreateHttpServer() {
  http_server::HttpServerPtr http_server;
  mojo::NetAddressPtr local_address(mojo::NetAddress::New());
  local_address->family = mojo::NET_ADDRESS_FAMILY_IPV4;
  local_address->ipv4 = mojo::NetAddressIPv4::New();
  local_address->ipv4->addr.resize(4);
  local_address->ipv4->addr[0] = 127;
  local_address->ipv4->addr[1] = 0;
  local_address->ipv4->addr[2] = 0;
  local_address->ipv4->addr[3] = 1;
  local_address->ipv4->port = 0;
  http_server_factory_->CreateHttpServer(GetProxy(&http_server).Pass(),
                                         local_address.Pass());
  return http_server.Pass();
}

void CheckServerResponse(mojo::URLResponsePtr response) {
  EXPECT_EQ(200u, response->status_code);
  std::string response_body;
  mojo::common::BlockingCopyToString(response->body.Pass(), &response_body);
  EXPECT_EQ(kExampleMessage, response_body);
  base::MessageLoop::current()->Quit();
}

// Verifies that the server responds to http GET requests using example
// GetHandler.
TEST_F(HttpServerApplicationTest, ServerResponse) {
  http_server::HttpServerPtr http_server(CreateHttpServer());
  uint16_t assigned_port;
  http_server->GetPort([&assigned_port](uint16_t p) { assigned_port = p; });
  http_server.WaitForIncomingMethodCall();

  HttpHandlerPtr http_handler_ptr;
  GetHandler handler(GetProxy(&http_handler_ptr).Pass());

  // Set the test handler and wait for confirmation.
  http_server->SetHandler("/test", http_handler_ptr.Pass(),
                          [](bool result) { EXPECT_TRUE(result); });
  http_server.WaitForIncomingMethodCall();

  mojo::URLLoaderPtr url_loader;
  network_service_->CreateURLLoader(GetProxy(&url_loader));

  mojo::URLRequestPtr url_request = mojo::URLRequest::New();
  url_request->url =
      base::StringPrintf("http://127.0.0.1:%u/test", assigned_port);
  url_loader->Start(url_request.Pass(), base::Bind(&CheckServerResponse));
  base::RunLoop run_loop;
  run_loop.Run();
}

// Verifies that the server correctly passes the POST request payload using
// example PostHandler.
TEST_F(HttpServerApplicationTest, PostData) {
  http_server::HttpServerPtr http_server(CreateHttpServer());
  uint16_t assigned_port;
  http_server->GetPort([&assigned_port](uint16_t p) { assigned_port = p; });
  http_server.WaitForIncomingMethodCall();

  HttpHandlerPtr http_handler_ptr;
  PostHandler handler(GetProxy(&http_handler_ptr).Pass());

  // Set the test handler and wait for confirmation.
  http_server->SetHandler("/post", http_handler_ptr.Pass(),
                          [](bool result) { EXPECT_TRUE(result); });
  http_server.WaitForIncomingMethodCall();

  mojo::URLLoaderPtr url_loader;
  network_service_->CreateURLLoader(GetProxy(&url_loader));

  mojo::URLRequestPtr url_request = mojo::URLRequest::New();
  url_request->url =
      base::StringPrintf("http://127.0.0.1:%u/post", assigned_port);
  url_request->method = "POST";
  url_request->body.resize(1);
  WriteMessageToDataPipe(kExampleMessage, &url_request->body[0]);

  url_loader->Start(url_request.Pass(), base::Bind(&CheckServerResponse));
  base::RunLoop run_loop;
  run_loop.Run();
}

}  // namespace http_server
