// 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/base_paths.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.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/public/interfaces/net_address.mojom.h"
#include "shell/kPingable.h"
#include "shell/test/pingable.mojom.h"

using mojo::String;

namespace {

std::string GetURL(uint16_t port, const std::string& path) {
  return base::StringPrintf("http://127.0.0.1:%u/%s",
                            static_cast<unsigned>(port), path.c_str());
}

class GetHandler : public http_server::HttpHandler {
 public:
  GetHandler(mojo::InterfaceRequest<http_server::HttpHandler> request,
             uint16_t port)
      : binding_(this, request.Pass()), port_(port) {}
  ~GetHandler() override {}

 private:
  // http_server::HttpHandler:
  void HandleRequest(http_server::HttpRequestPtr request,
                     const mojo::Callback<void(http_server::HttpResponsePtr)>&
                         callback) override {
    http_server::HttpResponsePtr response;
    if (StartsWithASCII(request->relative_url, "/app", true)) {
      response = http_server::CreateHttpResponse(
          200, std::string(shell::test::kPingable.data,
                           shell::test::kPingable.size));
      response->content_type = "application/octet-stream";
    } else if (request->relative_url == "/redirect") {
      response = http_server::HttpResponse::New();
      response->status_code = 302;
      response->custom_headers.insert("Location", GetURL(port_, "app"));
    } else {
      NOTREACHED();
    }

    callback.Run(response.Pass());
  }

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

  MOJO_DISALLOW_COPY_AND_ASSIGN(GetHandler);
};

typedef mojo::test::ApplicationTestBase ShellAppTest;

class ShellHTTPAppTest : public ShellAppTest {
 public:
  ShellHTTPAppTest() {}
  ~ShellHTTPAppTest() override {}

 protected:
  void SetUp() override {
    ShellAppTest::SetUp();

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

    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(mojo::GetProxy(&http_server_),
                                           local_address.Pass());

    http_server_->GetPort([this](uint16_t p) { port_ = p; });
    EXPECT_TRUE(http_server_.WaitForIncomingResponse());

    http_server::HttpHandlerPtr http_handler;
    handler_.reset(new GetHandler(mojo::GetProxy(&http_handler).Pass(), port_));
    http_server_->SetHandler(".*", http_handler.Pass(),
                             [](bool result) { EXPECT_TRUE(result); });
    EXPECT_TRUE(http_server_.WaitForIncomingResponse());
  }

  std::string GetURL(const std::string& path) { return ::GetURL(port_, path); }

  http_server::HttpServerFactoryPtr http_server_factory_;
  http_server::HttpServerPtr http_server_;
  scoped_ptr<GetHandler> handler_;
  uint16_t port_;

 private:
  MOJO_DISALLOW_COPY_AND_ASSIGN(ShellHTTPAppTest);
};

// Test that we can load apps over http.
TEST_F(ShellHTTPAppTest, Http) {
  PingablePtr pingable;
  application_impl()->ConnectToService(GetURL("app"), &pingable);
  pingable->Ping("hello",
                 [this](const String& app_url, const String& connection_url,
                        const String& message) {
                   EXPECT_EQ(GetURL("app"), app_url);
                   EXPECT_EQ(GetURL("app"), connection_url);
                   EXPECT_EQ("hello", message);
                   base::MessageLoop::current()->Quit();
                 });
  base::RunLoop().Run();
}

// Test that redirects work.
// TODO(aa): Test that apps receive the correct URL parameters.
TEST_F(ShellHTTPAppTest, Redirect) {
  PingablePtr pingable;
  application_impl()->ConnectToService(GetURL("redirect"), &pingable);
  pingable->Ping("hello",
                 [this](const String& app_url, const String& connection_url,
                        const String& message) {
                   EXPECT_EQ(GetURL("app"), app_url);
                   EXPECT_EQ(GetURL("app"), connection_url);
                   EXPECT_EQ("hello", message);
                   base::MessageLoop::current()->Quit();
                 });
  base::RunLoop().Run();
}

// Test that querystring is not considered when resolving http applications.
// TODO(aa|qsr): Fix this test on Linux ASAN http://crbug.com/463662
#if defined(ADDRESS_SANITIZER)
#define MAYBE_QueryHandling DISABLED_QueryHandling
#else
#define MAYBE_QueryHandling QueryHandling
#endif  // ADDRESS_SANITIZER
TEST_F(ShellHTTPAppTest, MAYBE_QueryHandling) {
  PingablePtr pingable1;
  PingablePtr pingable2;
  application_impl()->ConnectToService(GetURL("app?foo"), &pingable1);
  application_impl()->ConnectToService(GetURL("app?bar"), &pingable2);

  int num_responses = 0;
  auto callbacks_builder = [this, &num_responses](int query_index) {
    return [this, &num_responses, query_index](const String& app_url,
                                               const String& connection_url,
                                               const String& message) {
      EXPECT_EQ(GetURL("app"), app_url);
      EXPECT_EQ("hello", message);
      if (query_index == 1) {
        EXPECT_EQ(GetURL("app?foo"), connection_url);
      } else if (query_index == 2) {
        EXPECT_EQ(GetURL("app?bar"), connection_url);
      } else {
        CHECK(false);
      }
      ++num_responses;
      if (num_responses == 2)
        base::MessageLoop::current()->Quit();
    };
  };
  pingable1->Ping("hello", callbacks_builder(1));
  pingable2->Ping("hello", callbacks_builder(2));
  base::RunLoop().Run();
}

// mojo: URLs can have querystrings too
TEST_F(ShellAppTest, MojoURLQueryHandling) {
  PingablePtr pingable;
  application_impl()->ConnectToService("mojo:pingable_app?foo", &pingable);
  auto callback = [this](const String& app_url, const String& connection_url,
                         const String& message) {
    EXPECT_TRUE(EndsWith(app_url, "/pingable_app.mojo", true));
    EXPECT_EQ(app_url.To<std::string>() + "?foo", connection_url);
    EXPECT_EQ("hello", message);
    base::MessageLoop::current()->Quit();
  };
  pingable->Ping("hello", callback);
  base::RunLoop().Run();
}

}  // namespace
