// Copyright 2013 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/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/test_completion_callback.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_transaction_test_util.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/proxy_service.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/tools/quic/quic_in_memory_cache.h"
#include "net/tools/quic/quic_server.h"
#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
#include "net/tools/quic/test_tools/server_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

using base::StringPiece;
using net::tools::QuicInMemoryCache;
using net::tools::QuicServer;
using net::tools::test::QuicInMemoryCachePeer;
using net::tools::test::ServerThread;

namespace net {
namespace test {

namespace {

const char kResponseBody[] = "some arbitrary response body";

// Factory for creating HttpTransactions, used by TestTransactionConsumer.
class TestTransactionFactory : public HttpTransactionFactory {
 public:
  TestTransactionFactory(const HttpNetworkSession::Params& params)
      : session_(new HttpNetworkSession(params)) {}

  virtual ~TestTransactionFactory() {
  }

  // HttpTransactionFactory methods
  virtual int CreateTransaction(RequestPriority priority,
                                scoped_ptr<HttpTransaction>* trans) override {
    trans->reset(new HttpNetworkTransaction(priority, session_.get()));
    return OK;
  }

  virtual HttpCache* GetCache() override {
    return nullptr;
  }

  virtual HttpNetworkSession* GetSession() override { return session_.get(); };

 private:
  scoped_refptr<HttpNetworkSession> session_;
};

}  // namespace

class QuicEndToEndTest : public PlatformTest {
 protected:
  QuicEndToEndTest()
      : host_resolver_impl_(CreateResolverImpl()),
        host_resolver_(host_resolver_impl_.Pass()),
        ssl_config_service_(new SSLConfigServiceDefaults),
        proxy_service_(ProxyService::CreateDirect()),
        auth_handler_factory_(
            HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
        strike_register_no_startup_period_(false) {
    request_.method = "GET";
    request_.url = GURL("http://www.google.com/");
    request_.load_flags = 0;

    params_.enable_quic = true;
    params_.quic_clock = nullptr;
    params_.quic_random = nullptr;
    params_.host_resolver = &host_resolver_;
    params_.cert_verifier = &cert_verifier_;
    params_.transport_security_state = &transport_security_state_;
    params_.proxy_service = proxy_service_.get();
    params_.ssl_config_service = ssl_config_service_.get();
    params_.http_auth_handler_factory = auth_handler_factory_.get();
    params_.http_server_properties = http_server_properties.GetWeakPtr();
  }

  // Creates a mock host resolver in which www.google.com
  // resolves to localhost.
  static MockHostResolver* CreateResolverImpl() {
    MockHostResolver* resolver = new MockHostResolver();
    resolver->rules()->AddRule("www.google.com", "127.0.0.1");
    return resolver;
  }

  virtual void SetUp() {
    QuicInMemoryCachePeer::ResetForTests();
    StartServer();

    // Use a mapped host resolver so that request for www.google.com (port 80)
    // reach the server running on localhost.
    std::string map_rule = "MAP www.google.com www.google.com:" +
        base::IntToString(server_thread_->GetPort());
    EXPECT_TRUE(host_resolver_.AddRuleFromString(map_rule));

    // To simplify the test, and avoid the race with the HTTP request, we force
    // QUIC for these requests.
    params_.origin_to_force_quic_on =
        HostPortPair::FromString("www.google.com:80");

    transaction_factory_.reset(new TestTransactionFactory(params_));
  }

  virtual void TearDown() {
    StopServer();
    QuicInMemoryCachePeer::ResetForTests();
  }

  // Starts the QUIC server listening on a random port.
  void StartServer() {
    net::IPAddressNumber ip;
    CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &ip));
    server_address_ = IPEndPoint(ip, 0);
    server_config_.SetInitialFlowControlWindowToSend(
        kInitialSessionFlowControlWindowForTest);
    server_config_.SetInitialStreamFlowControlWindowToSend(
        kInitialStreamFlowControlWindowForTest);
    server_config_.SetInitialSessionFlowControlWindowToSend(
        kInitialSessionFlowControlWindowForTest);
    server_thread_.reset(new ServerThread(
         new QuicServer(server_config_, QuicSupportedVersions()),
         server_address_,
         strike_register_no_startup_period_));
    server_thread_->Initialize();
    server_address_ = IPEndPoint(server_address_.address(),
                                 server_thread_->GetPort());
    server_thread_->Start();
    server_started_ = true;
  }

  // Stops the QUIC server.
  void StopServer() {
    if (!server_started_) {
      return;
    }
    if (server_thread_.get()) {
      server_thread_->Quit();
      server_thread_->Join();
    }
  }

  // Adds an entry to the cache used by the QUIC server to serve
  // responses.
  void AddToCache(const StringPiece& method,
                  const StringPiece& path,
                  const StringPiece& version,
                  const StringPiece& response_code,
                  const StringPiece& response_detail,
                  const StringPiece& body) {
    QuicInMemoryCache::GetInstance()->AddSimpleResponse(
        method, path, version, response_code, response_detail, body);
  }

  // Populates |request_body_| with |length_| ASCII bytes.
  void GenerateBody(size_t length) {
    request_body_.clear();
    request_body_.reserve(length);
    for (size_t i = 0; i < length; ++i) {
      request_body_.append(1, static_cast<char>(32 + i % (126 - 32)));
    }
  }

  // Initializes |request_| for a post of |length| bytes.
  void InitializePostRequest(size_t length) {
    GenerateBody(length);
    ScopedVector<UploadElementReader> element_readers;
    element_readers.push_back(
        new UploadBytesElementReader(request_body_.data(),
                                     request_body_.length()));
    upload_data_stream_.reset(
        new ElementsUploadDataStream(element_readers.Pass(), 0));
    request_.method = "POST";
    request_.url = GURL("http://www.google.com/");
    request_.upload_data_stream = upload_data_stream_.get();
    ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
  }

  // Checks that |consumer| completed and received |status_line| and |body|.
  void CheckResponse(const TestTransactionConsumer& consumer,
                     const std::string& status_line,
                     const std::string& body) {
    ASSERT_TRUE(consumer.is_done());
    EXPECT_EQ(OK, consumer.error());
    EXPECT_EQ(status_line,
              consumer.response_info()->headers->GetStatusLine());
    EXPECT_EQ(body, consumer.content());
  }

  scoped_ptr<MockHostResolver> host_resolver_impl_;
  MappedHostResolver host_resolver_;
  MockCertVerifier cert_verifier_;
  TransportSecurityState transport_security_state_;
  scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
  scoped_ptr<ProxyService> proxy_service_;
  scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
  HttpServerPropertiesImpl http_server_properties;
  HttpNetworkSession::Params params_;
  scoped_ptr<TestTransactionFactory> transaction_factory_;
  HttpRequestInfo request_;
  std::string request_body_;
  scoped_ptr<UploadDataStream> upload_data_stream_;
  scoped_ptr<ServerThread> server_thread_;
  IPEndPoint server_address_;
  std::string server_hostname_;
  QuicConfig server_config_;
  bool server_started_;
  bool strike_register_no_startup_period_;
};

TEST_F(QuicEndToEndTest, LargeGetWithNoPacketLoss) {
  std::string response(10 * 1024, 'x');

  AddToCache("GET", request_.url.spec(),
             "HTTP/1.1", "200", "OK",
             response);

  TestTransactionConsumer consumer(DEFAULT_PRIORITY,
                                   transaction_factory_.get());
  consumer.Start(&request_, BoundNetLog());

  // Will terminate when the last consumer completes.
  base::MessageLoop::current()->Run();

  CheckResponse(consumer, "HTTP/1.1 200 OK", response);
}

// http://crbug.com/307284
TEST_F(QuicEndToEndTest, DISABLED_LargePostWithNoPacketLoss) {
  InitializePostRequest(10 * 1024 * 1024);

  AddToCache("POST", request_.url.spec(),
             "HTTP/1.1", "200", "OK",
             kResponseBody);

  TestTransactionConsumer consumer(DEFAULT_PRIORITY,
                                   transaction_factory_.get());
  consumer.Start(&request_, BoundNetLog());

  // Will terminate when the last consumer completes.
  base::MessageLoop::current()->Run();

  CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
}

TEST_F(QuicEndToEndTest, LargePostWithPacketLoss) {
  // FLAGS_fake_packet_loss_percentage = 30;
  InitializePostRequest(1024 * 1024);

  const char kResponseBody[] = "some really big response body";
  AddToCache("POST", request_.url.spec(),
             "HTTP/1.1", "200", "OK",
             kResponseBody);

  TestTransactionConsumer consumer(DEFAULT_PRIORITY,
                                   transaction_factory_.get());
  consumer.Start(&request_, BoundNetLog());

  // Will terminate when the last consumer completes.
  base::MessageLoop::current()->Run();

  CheckResponse(consumer, "HTTP/1.1 200 OK", kResponseBody);
}

TEST_F(QuicEndToEndTest, UberTest) {
  // FLAGS_fake_packet_loss_percentage = 30;

  const char kResponseBody[] = "some really big response body";
  AddToCache("GET", request_.url.spec(),
             "HTTP/1.1", "200", "OK",
             kResponseBody);

  std::vector<TestTransactionConsumer*> consumers;
  size_t num_requests = 100;
  for (size_t i = 0; i < num_requests; ++i) {
      TestTransactionConsumer* consumer =
          new TestTransactionConsumer(DEFAULT_PRIORITY,
                                      transaction_factory_.get());
      consumers.push_back(consumer);
      consumer->Start(&request_, BoundNetLog());
  }

  // Will terminate when the last consumer completes.
  base::MessageLoop::current()->Run();

  for (size_t i = 0; i < num_requests; ++i) {
    CheckResponse(*consumers[i], "HTTP/1.1 200 OK", kResponseBody);
  }
  STLDeleteElements(&consumers);
}

}  // namespace test
}  // namespace net
