// 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/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/proxy/proxy_resolver_v8.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

// 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

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