// 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/converters/base/base_type_converters.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/application/connect.h"
#include "mojo/public/cpp/system/macros.h"
#include "mojo/public/interfaces/application/application_connector.mojom.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 "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 (base::StartsWith(request->relative_url.To<base::StringPiece>(), "/app",
                         base::CompareCase::SENSITIVE)) {
      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();

    mojo::ConnectToService(application_impl()->shell(), "mojo:http_server",
                           GetProxy(&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(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(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;
  mojo::ConnectToService(application_impl()->shell(), GetURL("app"),
                         GetProxy(&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;
  mojo::ConnectToService(application_impl()->shell(), GetURL("redirect"),
                         GetProxy(&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;
  mojo::ConnectToService(application_impl()->shell(), GetURL("app?foo"),
                         GetProxy(&pingable1));
  mojo::ConnectToService(application_impl()->shell(), GetURL("app?bar"),
                         GetProxy(&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;
  mojo::ConnectToService(application_impl()->shell(), "mojo:pingable_app?foo",
                         GetProxy(&pingable));
  auto callback = [](const String& app_url, const String& connection_url,
                     const String& message) {
    EXPECT_TRUE(base::EndsWith(app_url.To<base::StringPiece>(),
                               "/pingable_app.mojo",
                               base::CompareCase::SENSITIVE));
    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();
}

void TestApplicationConnector(mojo::ApplicationConnector* app_connector) {
  PingablePtr pingable;
  ConnectToService(app_connector, "mojo:pingable_app", GetProxy(&pingable));
  auto callback = [](const String& app_url, const String& connection_url,
                     const String& message) {
    EXPECT_TRUE(base::EndsWith(app_url.To<base::StringPiece>(),
                               "/pingable_app.mojo",
                               base::CompareCase::SENSITIVE));
    EXPECT_EQ(app_url, connection_url);
    EXPECT_EQ("hello", message);
    base::MessageLoop::current()->Quit();
  };
  pingable->Ping("hello", callback);
  base::RunLoop().Run();
}

TEST_F(ShellAppTest, ApplicationConnector) {
  mojo::ApplicationConnectorPtr app_connector;
  app_connector.Bind(application_impl()->CreateApplicationConnector());
  TestApplicationConnector(app_connector.get());
}

TEST_F(ShellAppTest, ApplicationConnectorDuplicate) {
  mojo::ApplicationConnectorPtr app_connector1;
  app_connector1.Bind(application_impl()->CreateApplicationConnector());
  {
    SCOPED_TRACE("app_connector1");
    TestApplicationConnector(app_connector1.get());
  }

  mojo::ApplicationConnectorPtr app_connector2;
  app_connector1->Duplicate(GetProxy(&app_connector2));
  {
    SCOPED_TRACE("app_connector2");
    TestApplicationConnector(app_connector2.get());
  }

  // The first one should still work.
  {
    SCOPED_TRACE("app_connector1 again");
    TestApplicationConnector(app_connector1.get());
  }
}

}  // namespace
