// 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 "base/base_paths.h"
#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/test/perf_time_logger.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/proxy/proxy_info.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_WIN)
#include "net/proxy/proxy_resolver_winhttp.h"
#elif defined(OS_MACOSX)
#include "net/proxy/proxy_resolver_mac.h"
#endif

#if !defined(DISABLE_V8_IN_NET)
#include "net/proxy/proxy_resolver_v8.h"
#endif

// This class holds the URL to use for resolving, and the expected result.
// We track the expected result in order to make sure the performance
// test is actually resolving URLs properly, otherwise the perf numbers
// are meaningless :-)
struct PacQuery {
  const char* query_url;
  const char* expected_result;
};

// Entry listing which PAC scripts to load, and which URLs to try resolving.
// |queries| should be terminated by {NULL, NULL}. A sentinel is used
// rather than a length, to simplify using initializer lists.
struct PacPerfTest {
  const char* pac_name;
  PacQuery queries[100];

  // Returns the actual number of entries in |queries| (assumes NULL sentinel).
  int NumQueries() const;
};

// List of performance tests.
static PacPerfTest kPerfTests[] = {
  // This test uses an ad-blocker PAC script. This script is very heavily
  // regular expression oriented, and has no dependencies on the current
  // IP address, or DNS resolving of hosts.
  { "no-ads.pac",
    { // queries:
      {"http://www.google.com", "DIRECT"},
      {"http://www.imdb.com/photos/cmsicons/x", "PROXY 0.0.0.0:3421"},
      {"http://www.imdb.com/x", "DIRECT"},
      {"http://www.staples.com/", "DIRECT"},
      {"http://www.staples.com/pixeltracker/x", "PROXY 0.0.0.0:3421"},
      {"http://www.staples.com/pixel/x", "DIRECT"},
      {"http://www.foobar.com", "DIRECT"},
      {"http://www.foobarbaz.com/x/y/z", "DIRECT"},
      {"http://www.testurl1.com/index.html", "DIRECT"},
      {"http://www.testurl2.com", "DIRECT"},
      {"https://www.sample/pirate/arrrrrr", "DIRECT"},
      {NULL, NULL}
    },
  },
};

int PacPerfTest::NumQueries() const {
  for (size_t i = 0; i < arraysize(queries); ++i) {
    if (queries[i].query_url == NULL)
      return i;
  }
  NOTREACHED();  // Bad definition.
  return 0;
}

// The number of URLs to resolve when testing a PAC script.
const int kNumIterations = 500;

// Helper class to run through all the performance tests using the specified
// proxy resolver implementation.
class PacPerfSuiteRunner {
 public:
  // |resolver_name| is the label used when logging the results.
  PacPerfSuiteRunner(net::ProxyResolver* resolver,
                     const std::string& resolver_name)
      : resolver_(resolver),
        resolver_name_(resolver_name),
        test_server_(
            net::SpawnedTestServer::TYPE_HTTP,
            net::SpawnedTestServer::kLocalhost,
            base::FilePath(
                FILE_PATH_LITERAL("net/data/proxy_resolver_perftest"))) {
  }

  void RunAllTests() {
    ASSERT_TRUE(test_server_.Start());
    for (size_t i = 0; i < arraysize(kPerfTests); ++i) {
      const PacPerfTest& test_data = kPerfTests[i];
      RunTest(test_data.pac_name,
              test_data.queries,
              test_data.NumQueries());
    }
  }

 private:
  void RunTest(const std::string& script_name,
               const PacQuery* queries,
               int queries_len) {
    if (!resolver_->expects_pac_bytes()) {
      GURL pac_url =
          test_server_.GetURL(std::string("files/") + script_name);
      int rv = resolver_->SetPacScript(
          net::ProxyResolverScriptData::FromURL(pac_url),
          net::CompletionCallback());
      EXPECT_EQ(net::OK, rv);
    } else {
      LoadPacScriptIntoResolver(script_name);
    }

    // Do a query to warm things up. In the case of internal-fetch proxy
    // resolvers, the first resolve will be slow since it has to download
    // the PAC script.
    {
      net::ProxyInfo proxy_info;
      int result = resolver_->GetProxyForURL(
          GURL("http://www.warmup.com"), &proxy_info, net::CompletionCallback(),
          NULL, net::BoundNetLog());
      ASSERT_EQ(net::OK, result);
    }

    // Start the perf timer.
    std::string perf_test_name = resolver_name_ + "_" + script_name;
    base::PerfTimeLogger timer(perf_test_name.c_str());

    for (int i = 0; i < kNumIterations; ++i) {
      // Round-robin between URLs to resolve.
      const PacQuery& query = queries[i % queries_len];

      // Resolve.
      net::ProxyInfo proxy_info;
      int result = resolver_->GetProxyForURL(
          GURL(query.query_url), &proxy_info, net::CompletionCallback(), NULL,
          net::BoundNetLog());

      // Check that the result was correct. Note that ToPacString() and
      // ASSERT_EQ() are fast, so they won't skew the results.
      ASSERT_EQ(net::OK, result);
      ASSERT_EQ(query.expected_result, proxy_info.ToPacString());
    }

    // Print how long the test ran for.
    timer.Done();
  }

  // Read the PAC script from disk and initialize the proxy resolver with it.
  void LoadPacScriptIntoResolver(const std::string& script_name) {
    base::FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.AppendASCII("net");
    path = path.AppendASCII("data");
    path = path.AppendASCII("proxy_resolver_perftest");
    path = path.AppendASCII(script_name);

    // Try to read the file from disk.
    std::string file_contents;
    bool ok = base::ReadFileToString(path, &file_contents);

    // If we can't load the file from disk, something is misconfigured.
    LOG_IF(ERROR, !ok) << "Failed to read file: " << path.value();
    ASSERT_TRUE(ok);

    // Load the PAC script into the ProxyResolver.
    int rv = resolver_->SetPacScript(
        net::ProxyResolverScriptData::FromUTF8(file_contents),
        net::CompletionCallback());
    EXPECT_EQ(net::OK, rv);
  }

  net::ProxyResolver* resolver_;
  std::string resolver_name_;
  net::SpawnedTestServer test_server_;
};

#if defined(OS_WIN)
TEST(ProxyResolverPerfTest, ProxyResolverWinHttp) {
  net::ProxyResolverWinHttp resolver;
  PacPerfSuiteRunner runner(&resolver, "ProxyResolverWinHttp");
  runner.RunAllTests();
}
#elif defined(OS_MACOSX)
TEST(ProxyResolverPerfTest, ProxyResolverMac) {
  net::ProxyResolverMac resolver;
  PacPerfSuiteRunner runner(&resolver, "ProxyResolverMac");
  runner.RunAllTests();
}
#endif

#if !defined(DISABLE_V8_IN_NET)

class MockJSBindings : public net::ProxyResolverV8::JSBindings {
 public:
  MockJSBindings() {}

  virtual void Alert(const base::string16& message) OVERRIDE {
    CHECK(false);
  }

  virtual bool ResolveDns(const std::string& host,
                          ResolveDnsOperation op,
                          std::string* output,
                          bool* terminate) OVERRIDE {
    CHECK(false);
    return false;
  }

  virtual void OnError(int line_number,
                       const base::string16& message) OVERRIDE {
    CHECK(false);
  }
};

TEST(ProxyResolverPerfTest, ProxyResolverV8) {
  net::ProxyResolverV8::EnsureIsolateCreated();

  MockJSBindings js_bindings;
  net::ProxyResolverV8 resolver;
  resolver.set_js_bindings(&js_bindings);
  PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8");
  runner.RunAllTests();
}

#endif  // !defined(DISABLE_V8_IN_NET)
