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

  ~TestTransactionFactory() override {}

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

  HttpCache* GetCache() override { return nullptr; }

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

  void SetUp() override {
    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_));
  }

  void TearDown() override {
    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
