// Copyright 2017 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 <inttypes.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/memory_dump_manager_test_utils.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_config.h"
#include "base/trace_event/traced_value.h"
#include "net/base/load_timing_info.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_status_code.h"
#include "net/quic/crypto/proof_source_chromium.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/third_party/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quic/tools/quic_memory_cache_backend.h"
#include "net/tools/quic/quic_simple_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
#include "url/gurl.h"

using testing::_;
using testing::Invoke;
using testing::Contains;
using testing::Eq;
using testing::ByRef;
using base::trace_event::MemoryAllocatorDump;

namespace net {

namespace {

const int kAltSvcPort = 6121;
const char kOriginHost[] = "mail.example.com";
const char kAltSvcHost[] = "test.example.com";
// Used as a simple response from the server.
const char kHelloPath[] = "/hello.txt";
const char kHelloAltSvcResponse[] = "Hello from QUIC Server";
const char kHelloOriginResponse[] = "Hello from TCP Server";
const int kHelloStatus = 200;

std::unique_ptr<test_server::HttpResponse> HandleRequest(
    const test_server::HttpRequest& request) {
  std::unique_ptr<test_server::BasicHttpResponse> http_response(
      new test_server::BasicHttpResponse());
  http_response->AddCustomHeader(
      "Alt-Svc", base::StringPrintf(
                     "quic=\"%s:%d\"; v=\"%u\"", kAltSvcHost, kAltSvcPort,
                     HttpNetworkSession::Params().quic_supported_versions[0]));
  http_response->set_code(HTTP_OK);
  http_response->set_content(kHelloOriginResponse);
  http_response->set_content_type("text/plain");
  return std::move(http_response);
}

void PrintPerfTest(const std::string& name,
                   int value,
                   const std::string& unit) {
  const ::testing::TestInfo* test_info =
      ::testing::UnitTest::GetInstance()->current_test_info();
  perf_test::PrintResult(test_info->test_case_name(),
                         std::string(".") + test_info->name(), name,
                         static_cast<double>(value), unit, true);
}

class URLRequestQuicPerfTest : public ::testing::Test {
 protected:
  URLRequestQuicPerfTest() : message_loop_(new base::MessageLoopForIO()) {
    memory_dump_manager_ =
        base::trace_event::MemoryDumpManager::CreateInstanceForTesting();
    base::trace_event::InitializeMemoryDumpManagerForInProcessTesting(
        /*is_coordinator_process=*/false);
    memory_dump_manager_->set_dumper_registrations_ignored_for_testing(false);
    context_ = std::make_unique<TestURLRequestContext>(true);
    memory_dump_manager_->set_dumper_registrations_ignored_for_testing(true);
    StartTcpServer();
    StartQuicServer();

    // Host mapping.
    std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
    resolver->rules()->AddRule(kAltSvcHost, "127.0.0.1");
    host_resolver_.reset(new MappedHostResolver(std::move(resolver)));
    std::string map_rule = base::StringPrintf("MAP %s 127.0.0.1:%d",
                                              kOriginHost, tcp_server_->port());
    EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule));

    net::HttpNetworkSession::Context network_session_context;
    network_session_context.cert_verifier = &cert_verifier_;
    std::unique_ptr<HttpNetworkSession::Params> params(
        new HttpNetworkSession::Params);
    params->enable_quic = true;
    params->enable_user_alternate_protocol_ports = true;
    params->quic_allow_remote_alt_svc = true;
    context_->set_host_resolver(host_resolver_.get());
    context_->set_http_network_session_params(std::move(params));
    context_->set_cert_verifier(&cert_verifier_);
    context_->Init();
  }

  void TearDown() override {
    if (quic_server_) {
      quic_server_->Shutdown();
      // If possible, deliver the conncetion close packet to the client before
      // destruct the TestURLRequestContext.
      base::RunLoop().RunUntilIdle();
    }
    // |tcp_server_| shuts down in EmbeddedTestServer destructor.
    memory_dump_manager_.reset();
    message_loop_.reset();
  }

  std::unique_ptr<URLRequest> CreateRequest(const GURL& url,
                                            RequestPriority priority,
                                            URLRequest::Delegate* delegate) {
    return context_->CreateRequest(url, priority, delegate,
                                   TRAFFIC_ANNOTATION_FOR_TESTS);
  }

  URLRequestContext* context() const { return context_.get(); }

 private:
  void StartQuicServer() {
    quic::QuicConfig config;
    memory_cache_backend_.AddSimpleResponse(kOriginHost, kHelloPath,
                                            kHelloStatus, kHelloAltSvcResponse);
    quic_server_.reset(new QuicSimpleServer(
        quic::test::crypto_test_utils::ProofSourceForTesting(), config,
        quic::QuicCryptoServerConfig::ConfigOptions(),
        quic::AllSupportedVersions(), &memory_cache_backend_));
    int rv = quic_server_->Listen(
        net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kAltSvcPort));
    ASSERT_GE(rv, 0) << "Quic server fails to start";

    CertVerifyResult verify_result;
    verify_result.verified_cert = ImportCertFromFile(
        GetTestCertsDirectory(), "quic-chain.pem");
    cert_verifier_.AddResultForCert(verify_result.verified_cert.get(),
                                    verify_result, OK);
  }

  void StartTcpServer() {
    tcp_server_ = std::make_unique<EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    tcp_server_->RegisterRequestHandler(base::BindRepeating(&HandleRequest));
    ASSERT_TRUE(tcp_server_->Start()) << "HTTP/1.1 server fails to start";

    CertVerifyResult verify_result;
    verify_result.verified_cert = tcp_server_->GetCertificate();
    cert_verifier_.AddResultForCert(tcp_server_->GetCertificate(),
                                    verify_result, OK);
  }

  std::unique_ptr<base::trace_event::MemoryDumpManager> memory_dump_manager_;
  std::unique_ptr<MappedHostResolver> host_resolver_;
  std::unique_ptr<EmbeddedTestServer> tcp_server_;
  std::unique_ptr<QuicSimpleServer> quic_server_;
  std::unique_ptr<base::MessageLoop> message_loop_;
  std::unique_ptr<TestURLRequestContext> context_;
  quic::QuicMemoryCacheBackend memory_cache_backend_;
  MockCertVerifier cert_verifier_;
};

void CheckScalarInDump(const MemoryAllocatorDump* dump,
                       const std::string& name,
                       const char* expected_units,
                       uint64_t expected_value) {
  MemoryAllocatorDump::Entry expected(name, expected_units, expected_value);
  EXPECT_THAT(dump->entries(), Contains(Eq(ByRef(expected))));
}

}  // namespace

TEST_F(URLRequestQuicPerfTest, TestGetRequest) {
  bool quic_succeeded = false;
  GURL url(base::StringPrintf("https://%s%s", kOriginHost, kHelloPath));
  base::TimeTicks start = base::TimeTicks::Now();
  const int kNumRequest = 1000;
  for (int i = 0; i < kNumRequest; ++i) {
    TestDelegate delegate;
    std::unique_ptr<URLRequest> request =
        CreateRequest(url, DEFAULT_PRIORITY, &delegate);

    request->Start();
    EXPECT_TRUE(request->is_pending());
    base::RunLoop().Run();

    EXPECT_TRUE(request->status().is_success());
    if (delegate.data_received() == kHelloAltSvcResponse) {
      quic_succeeded = true;
    } else {
      EXPECT_EQ(kHelloOriginResponse, delegate.data_received());
    }
  }
  base::TimeTicks end = base::TimeTicks::Now();
  PrintPerfTest("time", (end - start).InMilliseconds() / kNumRequest, "ms");

  EXPECT_TRUE(quic_succeeded);
  base::trace_event::MemoryDumpManager::GetInstance()->SetupForTracing(
      base::trace_event::TraceConfig::MemoryDumpConfig());

  base::RunLoop run_loop;
  base::trace_event::MemoryDumpRequestArgs args{
      1 /* dump_guid*/, base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
      base::trace_event::MemoryDumpLevelOfDetail::LIGHT};

  auto on_memory_dump_done =
      [](base::Closure quit_closure, const URLRequestContext* context,
         bool success, uint64_t dump_guid,
         std::unique_ptr<base::trace_event::ProcessMemoryDump> pmd) {
        ASSERT_TRUE(success);
        const auto& allocator_dumps = pmd->allocator_dumps();

        auto it = allocator_dumps.find(
            base::StringPrintf("net/url_request_context/unknown/0x%" PRIxPTR,
                               reinterpret_cast<uintptr_t>(context)));
        ASSERT_NE(allocator_dumps.end(), it);
        MemoryAllocatorDump* url_request_context_dump = it->second.get();
        CheckScalarInDump(
            url_request_context_dump,
            base::trace_event::MemoryAllocatorDump::kNameObjectCount,
            base::trace_event::MemoryAllocatorDump::kUnitsObjects, 0);

        it = allocator_dumps.find(base::StringPrintf(
            "net/http_network_session_0x%" PRIxPTR "/quic_stream_factory",
            reinterpret_cast<uintptr_t>(
                context->http_transaction_factory()->GetSession())));
        ASSERT_NE(allocator_dumps.end(), it);
        MemoryAllocatorDump* quic_stream_factory_dump = it->second.get();
        CheckScalarInDump(quic_stream_factory_dump, "active_jobs",
                          base::trace_event::MemoryAllocatorDump::kUnitsObjects,
                          0);

        PrintPerfTest("active_quic_jobs", 0, "count");
        CheckScalarInDump(quic_stream_factory_dump, "all_sessions",
                          base::trace_event::MemoryAllocatorDump::kUnitsObjects,
                          1);
        PrintPerfTest("active_quic_sessions", 1, "count");

        std::string stream_factory_dump_name = base::StringPrintf(
            "net/http_network_session_0x%" PRIxPTR "/stream_factory",
            reinterpret_cast<uintptr_t>(
                context->http_transaction_factory()->GetSession()));
        ASSERT_EQ(0u, allocator_dumps.count(stream_factory_dump_name));
        quit_closure.Run();

      };
  base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump(
      args, base::Bind(on_memory_dump_done, run_loop.QuitClosure(), context()));
  run_loop.Run();
  base::trace_event::MemoryDumpManager::GetInstance()->TeardownForTracing();
}

}  // namespace net
