// Copyright (c) 2012 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 <utility>

#include "dial_http_server.h"
#include "dial_service_handler.h"

#include "base/strings/string_split.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/dial/dial_service.h"
#include "net/dial/dial_test_helpers.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/server/http_server_request_info.h"
#include "net/socket/client_socket_factory.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::Return;

// Data our mock service handler will send to the dial HTTP server.
struct ResponseData {
  ResponseData() : response_code_(0), succeeded_(false) {}
  std::string response_body_;
  std::string mime_type_;
  std::vector<std::pair<std::string, std::string>> headers_;
  int response_code_;
  bool succeeded_;
};

// Test fixture
class DialHttpServerTest : public testing::Test {
 public:
  std::unique_ptr<DialService> dial_service_;
  IPEndPoint addr_;
  std::unique_ptr<HttpNetworkSession> session_;
  std::unique_ptr<HttpNetworkTransaction> client_;
  scoped_refptr<MockServiceHandler> handler_;
  std::unique_ptr<ResponseData> test_response_;
  // We need an IO message loop for TCP connection.
  base::MessageLoopForIO message_loop_for_io_;

  DialHttpServerTest() { handler_ = new MockServiceHandler("Foo"); }

  void InitHttpClientLibrary() {
    HttpNetworkSession::Params params;
    HttpNetworkSession::Context context;
    context.proxy_resolution_service =
        ProxyResolutionService::CreateDirect().release();
    context.http_server_properties = new HttpServerPropertiesImpl();
    context.ssl_config_service = new SSLConfigServiceDefaults();
    context.http_server_properties = new HttpServerPropertiesImpl();
    context.transport_security_state = new TransportSecurityState();
    context.cert_transparency_verifier = new MultiLogCTVerifier();
    context.ct_policy_enforcer = new DefaultCTPolicyEnforcer();
    context.host_resolver = new MockHostResolver();
    session_.reset(new HttpNetworkSession(params, context));
    client_.reset(new HttpNetworkTransaction(net::RequestPriority::MEDIUM,
                                             session_.get()));
  }

  virtual void SetUp() override {
    dial_service_.reset(new DialService());
    dial_service_->Register(handler_);
    EXPECT_EQ(OK, dial_service_->http_server()->GetLocalAddress(&addr_));
    InitHttpClientLibrary();
  }

  virtual void TearDown() override {
    dial_service_->Deregister(handler_);
    dial_service_.reset(NULL);

    const HttpNetworkSession::Context& context = session_->context();
    delete context.proxy_resolution_service;
    delete context.http_server_properties;
    delete context.host_resolver;
    delete context.ssl_config_service;
  }

  const HttpResponseInfo* GetResponse(const HttpRequestInfo& req) {
    TestCompletionCallback callback;
    int rv = client_->Start(&req, callback.callback(), NetLogWithSource());

    if (rv == ERR_IO_PENDING) {
      // FIXME: This call can be flaky: It may wait forever.
      // NOTE: I think flakiness here has been fixed in Starboard, by explicitly
      // waking up the message pump when calling QuitWhenIdle.
      callback.WaitForResult();
    }
    return client_->GetResponseInfo();
  }

  HttpRequestInfo CreateRequest(const std::string& method,
                                const std::string& path) {
    HttpRequestInfo req;
    req.url = GURL("http://" + addr_.ToString() + path);
    req.method = method;
    req.load_flags = LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE;
    return req;
  }

  void Capture(const std::string& path,
               const HttpServerRequestInfo& request,
               const DialServiceHandler::CompletionCB& on_completion) {
    if (!test_response_->succeeded_) {
      on_completion.Run(std::unique_ptr<HttpServerResponseInfo>());
      return;
    }
    // This function simulates a DialServiceHandler response.
    std::unique_ptr<HttpServerResponseInfo> response(new HttpServerResponseInfo(
        net::HttpStatusCode(test_response_->response_code_)));
    response->SetBody(test_response_->response_body_,
                      test_response_->mime_type_);
    for (auto i : test_response_->headers_) {
      response->AddHeader(i.first, i.second);
    }

    on_completion.Run(std::move(response));
  }

  void DoResponseCheck(const HttpResponseInfo* resp, bool has_contents) {
    EXPECT_EQ(test_response_->response_code_, resp->headers->response_code());

    for (auto it = test_response_->headers_.begin();
         it != test_response_->headers_.end(); ++it) {
      EXPECT_TRUE(resp->headers->HasHeaderValue(it->first, it->second));
    }

    int64 content_length = resp->headers->GetContentLength();
    if (!has_contents) {
      EXPECT_EQ(0, content_length);
      return;
    }

    ASSERT_NE(0, content_length);  // if failed, no point continuing.

    scoped_refptr<IOBuffer> buffer(
        new IOBuffer(static_cast<size_t>(content_length)));
    TestCompletionCallback callback;
    int rv = client_->Read(buffer, content_length, callback.callback());
    if (rv == net::ERR_IO_PENDING) {
      rv = callback.WaitForResult();
    }

    EXPECT_EQ(test_response_->response_body_.length(), rv);
    EXPECT_EQ(0, strncmp(buffer->data(), test_response_->response_body_.data(),
                         test_response_->response_body_.length()));
  }
};

TEST_F(DialHttpServerTest, SendManifest) {
  HttpRequestInfo req = CreateRequest("GET", "/dd.xml");
  const HttpResponseInfo* resp = GetResponse(req);
  ASSERT_TRUE(resp != NULL);

  std::string store;
  EXPECT_EQ(HTTP_OK, resp->headers->response_code());

  EXPECT_TRUE(resp->headers->GetMimeType(&store));
  EXPECT_EQ("text/xml", store);
  EXPECT_TRUE(resp->headers->GetCharset(&store));
  EXPECT_EQ("utf-8", store);

  EXPECT_TRUE(resp->headers->HasHeaderValue(
      "APPLICATION-URL", "http://" + addr_.ToString() + "/apps/"));

  int64 content_length = resp->headers->GetContentLength();
  ASSERT_NE(0, content_length);  // if failed, no point continuing.

  scoped_refptr<IOBuffer> buffer(
      new IOBuffer(static_cast<size_t>(content_length)));
  TestCompletionCallback callback;
  int rv = client_->Read(buffer, content_length, callback.callback());
  if (rv == net::ERR_IO_PENDING) {
    rv = callback.WaitForResult();
  }
  EXPECT_EQ(content_length, rv);
}

TEST_F(DialHttpServerTest, CurrentRunningAppRedirect) {
  HttpRequestInfo req = CreateRequest("GET", "/apps/");
  const HttpResponseInfo* resp = GetResponse(req);
  ASSERT_TRUE(resp != NULL);

  std::string store;
  EXPECT_EQ(HTTP_FOUND, resp->headers->response_code());

  EXPECT_FALSE(resp->headers->GetMimeType(&store));
  EXPECT_FALSE(resp->headers->GetCharset(&store));

  EXPECT_TRUE(resp->headers->HasHeaderValue(
      "Location", "http://" + addr_.ToString() + "/apps/YouTube"));

  int64 content_length = resp->headers->GetContentLength();
  EXPECT_EQ(0, content_length);
}

TEST_F(DialHttpServerTest, AllOtherRequests) {
  struct TestStruct {
    const char* method;
    const char* path;
    const int response_code_received;
  } tests[] = {
      {"GET", "/", HTTP_NOT_FOUND},
      {"GET", "/etc", HTTP_NOT_FOUND},
      {"POST", "/dd.xml", HTTP_NOT_FOUND},
      {"POST", "/apps/YouTube", HTTP_NOT_FOUND},
  };

  for (int i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
    HttpRequestInfo req = CreateRequest(tests[i].method, tests[i].path);
    const HttpResponseInfo* resp = GetResponse(req);
    ASSERT_TRUE(resp != NULL);

    EXPECT_EQ(tests[i].response_code_received, resp->headers->response_code());
  }
}

TEST_F(DialHttpServerTest, CallbackNormalTest) {
  test_response_.reset(new ResponseData());
  test_response_->succeeded_ = true;
  test_response_->response_body_ = "App Test";
  test_response_->mime_type_ = "text/plain; charset=\"utf-8\"";
  test_response_->response_code_ = HTTP_OK;
  test_response_->headers_.push_back(
      std::make_pair<std::string, std::string>("X-Test-Header", "Baz"));

  const HttpRequestInfo& req = CreateRequest("GET", "/apps/Foo/bar");
  EXPECT_CALL(*handler_, HandleRequest(Eq("/bar"), _, _))
      .WillOnce(DoAll(Invoke(this, &DialHttpServerTest::Capture), Return()));

  const HttpResponseInfo* resp = GetResponse(req);
  ASSERT_TRUE(resp != NULL);
  DoResponseCheck(resp, true);

  std::string store;
  EXPECT_TRUE(resp->headers->GetMimeType(&store));
  EXPECT_EQ("text/plain", store);
  EXPECT_TRUE(resp->headers->GetCharset(&store));
  EXPECT_EQ("utf-8", store);
}

TEST_F(DialHttpServerTest, CallbackExceptionInServiceHandler) {
  // succeeded_ = false means the HTTP server should send us a 404.
  test_response_.reset(new ResponseData());
  test_response_->succeeded_ = false;
  test_response_->response_body_ = "App Test";
  test_response_->mime_type_ = "text/plain; charset=\"utf-8\"";
  test_response_->response_code_ = HTTP_OK;

  const HttpRequestInfo& req = CreateRequest("GET", "/apps/Foo/?throw=1");
  EXPECT_CALL(*handler_, HandleRequest(Eq("/?throw=1"), _, _))
      .WillOnce(DoAll(Invoke(this, &DialHttpServerTest::Capture), Return()));

  const HttpResponseInfo* resp = GetResponse(req);
  ASSERT_TRUE(resp != NULL);
  EXPECT_EQ(HTTP_NOT_FOUND, resp->headers->response_code());
}

TEST_F(DialHttpServerTest, CallbackHandleRequestReturnsFalse) {
  test_response_.reset(new ResponseData());
  test_response_->response_code_ = HTTP_NOT_FOUND;
  const HttpRequestInfo& req = CreateRequest("GET", "/apps/Foo/false/app");
  EXPECT_CALL(*handler_, HandleRequest(Eq("/false/app"), _, _))
      .WillOnce(DoAll(Invoke(this, &DialHttpServerTest::Capture), Return()));

  const HttpResponseInfo* resp = GetResponse(req);
  ASSERT_TRUE(resp != NULL);
  EXPECT_EQ(HTTP_NOT_FOUND, resp->headers->response_code());
}

// Ensure src address is not IFADDR_ANY or lo. We need some IP addresses here!
TEST_F(DialHttpServerTest, GetLocalAddress) {
  EXPECT_STRNE("0.0.0.0", addr_.ToStringWithoutPort().c_str());
  EXPECT_STRNE("127.0.0.1", addr_.ToStringWithoutPort().c_str());
}

}  // namespace net
