// 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/data_pipe_utils/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/cpp/http_server_util.h"
#include "mojo/services/http_server/interfaces/http_server.mojom.h"
#include "mojo/services/http_server/interfaces/http_server_factory.mojom.h"
#include "mojo/services/network/interfaces/net_address.mojom.h"
#include "mojo/services/network/interfaces/network_service.mojom.h"
#include "mojo/services/network/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,
                                       static_cast<uint32_t>(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 {}

 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 {}

 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()->ConnectToServiceDeprecated("mojo:http_server",
                                                   &http_server_factory_);
    application_impl()->ConnectToServiceDeprecated("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::NetAddressFamily::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;
}

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.WaitForIncomingResponse();

  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.WaitForIncomingResponse();

  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.WaitForIncomingResponse();

  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.WaitForIncomingResponse();

  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
