// Copyright (c) 2011 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/compiler_specific.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
#include "net/base/net_log_unittest.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_js_bindings.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {
namespace {

// Javascript bindings for ProxyResolverV8, which returns mock values.
// Each time one of the bindings is called into, we push the input into a
// list, for later verification.
class MockJSBindings : public ProxyResolverJSBindings {
 public:
  MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}

  virtual void Alert(const string16& message) OVERRIDE {
    VLOG(1) << "PAC-alert: " << message;  // Helpful when debugging.
    alerts.push_back(UTF16ToUTF8(message));
  }

  virtual bool MyIpAddress(std::string* ip_address) OVERRIDE {
    my_ip_address_count++;
    *ip_address = my_ip_address_result;
    return !my_ip_address_result.empty();
  }

  virtual bool MyIpAddressEx(std::string* ip_address_list) OVERRIDE {
    my_ip_address_ex_count++;
    *ip_address_list = my_ip_address_ex_result;
    return !my_ip_address_ex_result.empty();
  }

  virtual bool DnsResolve(const std::string& host, std::string* ip_address)
      OVERRIDE {
    dns_resolves.push_back(host);
    *ip_address = dns_resolve_result;
    return !dns_resolve_result.empty();
  }

  virtual bool DnsResolveEx(const std::string& host,
                            std::string* ip_address_list) OVERRIDE {
    dns_resolves_ex.push_back(host);
    *ip_address_list = dns_resolve_ex_result;
    return !dns_resolve_ex_result.empty();
  }

  virtual void OnError(int line_number, const string16& message) OVERRIDE {
    // Helpful when debugging.
    VLOG(1) << "PAC-error: [" << line_number << "] " << message;

    errors.push_back(UTF16ToUTF8(message));
    errors_line_number.push_back(line_number);
  }

  virtual void Shutdown() OVERRIDE {}

  // Mock values to return.
  std::string my_ip_address_result;
  std::string my_ip_address_ex_result;
  std::string dns_resolve_result;
  std::string dns_resolve_ex_result;

  // Inputs we got called with.
  std::vector<std::string> alerts;
  std::vector<std::string> errors;
  std::vector<int> errors_line_number;
  std::vector<std::string> dns_resolves;
  std::vector<std::string> dns_resolves_ex;
  int my_ip_address_count;
  int my_ip_address_ex_count;
};

// This is the same as ProxyResolverV8, but it uses mock bindings in place of
// the default bindings, and has a helper function to load PAC scripts from
// disk.
class ProxyResolverV8WithMockBindings : public ProxyResolverV8 {
 public:
  ProxyResolverV8WithMockBindings() : ProxyResolverV8(new MockJSBindings()) {}

  MockJSBindings* mock_js_bindings() const {
    return reinterpret_cast<MockJSBindings*>(js_bindings());
  }

  // Initialize with the PAC script data at |filename|.
  int SetPacScriptFromDisk(const char* filename) {
    FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.AppendASCII("net");
    path = path.AppendASCII("data");
    path = path.AppendASCII("proxy_resolver_v8_unittest");
    path = path.AppendASCII(filename);

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

    // If we can't load the file from disk, something is misconfigured.
    if (!ok) {
      LOG(ERROR) << "Failed to read file: " << path.value();
      return ERR_UNEXPECTED;
    }

    // Load the PAC script into the ProxyResolver.
    return SetPacScript(ProxyResolverScriptData::FromUTF8(file_contents),
                        NULL);
  }
};

// Doesn't really matter what these values are for many of the tests.
const GURL kQueryUrl("http://www.google.com");
const GURL kPacUrl;


TEST(ProxyResolverV8Test, Direct) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("direct.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   log.bound());

  EXPECT_EQ(OK, result);
  EXPECT_TRUE(proxy_info.is_direct());

  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());

  net::CapturingNetLog::EntryList entries;
  log.GetEntries(&entries);
  // No bindings were called, so no log entries.
  EXPECT_EQ(0u, entries.size());
}

TEST(ProxyResolverV8Test, ReturnEmptyString) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("return_empty_string.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(OK, result);
  EXPECT_TRUE(proxy_info.is_direct());

  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
}

TEST(ProxyResolverV8Test, Basic) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("passthrough.js");
  EXPECT_EQ(OK, result);

  // The "FindProxyForURL" of this PAC script simply concatenates all of the
  // arguments into a pseudo-host. The purpose of this test is to verify that
  // the correct arguments are being passed to FindProxyForURL().
  {
    ProxyInfo proxy_info;
    result = resolver.GetProxyForURL(GURL("http://query.com/path"),
                                     &proxy_info, NULL, NULL, BoundNetLog());
    EXPECT_EQ(OK, result);
    EXPECT_EQ("http.query.com.path.query.com:80",
              proxy_info.proxy_server().ToURI());
  }
  {
    ProxyInfo proxy_info;
    int result = resolver.GetProxyForURL(GURL("ftp://query.com:90/path"),
                                         &proxy_info, NULL, NULL,
                                         BoundNetLog());
    EXPECT_EQ(OK, result);
    // Note that FindProxyForURL(url, host) does not expect |host| to contain
    // the port number.
    EXPECT_EQ("ftp.query.com.90.path.query.com:80",
              proxy_info.proxy_server().ToURI());

    EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
    EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
  }

  // We call this so we'll have code coverage of the function and valgrind will
  // make sure nothing bad happens.
  //
  // NOTE: This is here instead of in its own test so that we'll be calling it
  // after having done something, in hopes it won't be a no-op.
  resolver.PurgeMemory();
}

TEST(ProxyResolverV8Test, BadReturnType) {
  // These are the filenames of PAC scripts which each return a non-string
  // types for FindProxyForURL(). They should all fail with
  // ERR_PAC_SCRIPT_FAILED.
  static const char* const filenames[] = {
      "return_undefined.js",
      "return_integer.js",
      "return_function.js",
      "return_object.js",
      // TODO(eroman): Should 'null' be considered equivalent to "DIRECT" ?
      "return_null.js"
  };

  for (size_t i = 0; i < arraysize(filenames); ++i) {
    ProxyResolverV8WithMockBindings resolver;
    int result = resolver.SetPacScriptFromDisk(filenames[i]);
    EXPECT_EQ(OK, result);

    ProxyInfo proxy_info;
    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                     BoundNetLog());

    EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

    MockJSBindings* bindings = resolver.mock_js_bindings();
    EXPECT_EQ(0U, bindings->alerts.size());
    ASSERT_EQ(1U, bindings->errors.size());
    EXPECT_EQ("FindProxyForURL() did not return a string.",
              bindings->errors[0]);
    EXPECT_EQ(-1, bindings->errors_line_number[0]);
  }
}

// Try using a PAC script which defines no "FindProxyForURL" function.
TEST(ProxyResolverV8Test, NoEntryPoint) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("no_entrypoint.js");
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(ERR_FAILED, result);
}

// Try loading a malformed PAC script.
TEST(ProxyResolverV8Test, ParseError) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("missing_close_brace.js");
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(ERR_FAILED, result);

  MockJSBindings* bindings = resolver.mock_js_bindings();
  EXPECT_EQ(0U, bindings->alerts.size());

  // We get one error during compilation.
  ASSERT_EQ(1U, bindings->errors.size());

  EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
            bindings->errors[0]);
  EXPECT_EQ(0, bindings->errors_line_number[0]);
}

// Run a PAC script several times, which has side-effects.
TEST(ProxyResolverV8Test, SideEffects) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("side_effects.js");

  // The PAC script increments a counter each time we invoke it.
  for (int i = 0; i < 3; ++i) {
    ProxyInfo proxy_info;
    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                     BoundNetLog());
    EXPECT_EQ(OK, result);
    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
              proxy_info.proxy_server().ToURI());
  }

  // Reload the script -- the javascript environment should be reset, hence
  // the counter starts over.
  result = resolver.SetPacScriptFromDisk("side_effects.js");
  EXPECT_EQ(OK, result);

  for (int i = 0; i < 3; ++i) {
    ProxyInfo proxy_info;
    result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                     BoundNetLog());
    EXPECT_EQ(OK, result);
    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
              proxy_info.proxy_server().ToURI());
  }
}

// Execute a PAC script which throws an exception in FindProxyForURL.
TEST(ProxyResolverV8Test, UnhandledException) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("unhandled_exception.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

  MockJSBindings* bindings = resolver.mock_js_bindings();
  EXPECT_EQ(0U, bindings->alerts.size());
  ASSERT_EQ(1U, bindings->errors.size());
  EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
            bindings->errors[0]);
  EXPECT_EQ(3, bindings->errors_line_number[0]);
}

TEST(ProxyResolverV8Test, ReturnUnicode) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("return_unicode.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  // The result from this resolve was unparseable, because it
  // wasn't ASCII.
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
}

// Test the PAC library functions that we expose in the JS environmnet.
TEST(ProxyResolverV8Test, JavascriptLibrary) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("pac_library_unittest.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  // If the javascript side of this unit-test fails, it will throw a javascript
  // exception. Otherwise it will return "PROXY success:80".
  EXPECT_EQ(OK, result);
  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());

  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
}

// Try resolving when SetPacScriptByData() has not been called.
TEST(ProxyResolverV8Test, NoSetPacScript) {
  ProxyResolverV8WithMockBindings resolver;

  ProxyInfo proxy_info;

  // Resolve should fail, as we are not yet initialized with a script.
  int result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                       BoundNetLog());
  EXPECT_EQ(ERR_FAILED, result);

  // Initialize it.
  result = resolver.SetPacScriptFromDisk("direct.js");
  EXPECT_EQ(OK, result);

  // Resolve should now succeed.
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());
  EXPECT_EQ(OK, result);

  // Clear it, by initializing with an empty string.
  resolver.SetPacScript(
      ProxyResolverScriptData::FromUTF16(string16()), NULL);

  // Resolve should fail again now.
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());
  EXPECT_EQ(ERR_FAILED, result);

  // Load a good script once more.
  result = resolver.SetPacScriptFromDisk("direct.js");
  EXPECT_EQ(OK, result);
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());
  EXPECT_EQ(OK, result);

  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
}

// Test marshalling/un-marshalling of values between C++/V8.
TEST(ProxyResolverV8Test, V8Bindings) {
  ProxyResolverV8WithMockBindings resolver;
  MockJSBindings* bindings = resolver.mock_js_bindings();
  bindings->dns_resolve_result = "127.0.0.1";
  int result = resolver.SetPacScriptFromDisk("bindings.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(OK, result);
  EXPECT_TRUE(proxy_info.is_direct());

  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());

  // Alert was called 5 times.
  ASSERT_EQ(5U, bindings->alerts.size());
  EXPECT_EQ("undefined", bindings->alerts[0]);
  EXPECT_EQ("null", bindings->alerts[1]);
  EXPECT_EQ("undefined", bindings->alerts[2]);
  EXPECT_EQ("[object Object]", bindings->alerts[3]);
  EXPECT_EQ("exception from calling toString()", bindings->alerts[4]);

  // DnsResolve was called 8 times, however only 2 of those were string
  // parameters. (so 6 of them failed immediately).
  ASSERT_EQ(2U, bindings->dns_resolves.size());
  EXPECT_EQ("", bindings->dns_resolves[0]);
  EXPECT_EQ("arg1", bindings->dns_resolves[1]);

  // MyIpAddress was called two times.
  EXPECT_EQ(2, bindings->my_ip_address_count);

  // MyIpAddressEx was called once.
  EXPECT_EQ(1, bindings->my_ip_address_ex_count);

  // DnsResolveEx was called 2 times.
  ASSERT_EQ(2U, bindings->dns_resolves_ex.size());
  EXPECT_EQ("is_resolvable", bindings->dns_resolves_ex[0]);
  EXPECT_EQ("foobar", bindings->dns_resolves_ex[1]);
}

// Test calling a binding (myIpAddress()) from the script's global scope.
// http://crbug.com/40026
TEST(ProxyResolverV8Test, BindingCalledDuringInitialization) {
  ProxyResolverV8WithMockBindings resolver;

  int result = resolver.SetPacScriptFromDisk("binding_from_global.js");
  EXPECT_EQ(OK, result);

  MockJSBindings* bindings = resolver.mock_js_bindings();

  // myIpAddress() got called during initialization of the script.
  EXPECT_EQ(1, bindings->my_ip_address_count);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(OK, result);
  EXPECT_FALSE(proxy_info.is_direct());
  EXPECT_EQ("127.0.0.1:80", proxy_info.proxy_server().ToURI());

  // Check that no other bindings were called.
  EXPECT_EQ(0U, bindings->errors.size());
  ASSERT_EQ(0U, bindings->alerts.size());
  ASSERT_EQ(0U, bindings->dns_resolves.size());
  EXPECT_EQ(0, bindings->my_ip_address_ex_count);
  ASSERT_EQ(0U, bindings->dns_resolves_ex.size());
}

// Try loading a PAC script that ends with a comment and has no terminal
// newline. This should not cause problems with the PAC utility functions
// that we add to the script's environment.
// http://crbug.com/22864
TEST(ProxyResolverV8Test, EndsWithCommentNoNewline) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("ends_with_comment.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   log.bound());

  EXPECT_EQ(OK, result);
  EXPECT_FALSE(proxy_info.is_direct());
  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
}

// Try loading a PAC script that ends with a statement and has no terminal
// newline. This should not cause problems with the PAC utility functions
// that we add to the script's environment.
// http://crbug.com/22864
TEST(ProxyResolverV8Test, EndsWithStatementNoNewline) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk(
      "ends_with_statement_no_semicolon.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   log.bound());

  EXPECT_EQ(OK, result);
  EXPECT_FALSE(proxy_info.is_direct());
  EXPECT_EQ("success:3", proxy_info.proxy_server().ToURI());
}

// Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
// dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
// returns empty string (failure). This simulates the return values from
// those functions when the underlying DNS resolution fails.
TEST(ProxyResolverV8Test, DNSResolutionFailure) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("dns_fail.js");
  EXPECT_EQ(OK, result);

  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(OK, result);
  EXPECT_FALSE(proxy_info.is_direct());
  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
}

TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
  ProxyResolverV8WithMockBindings resolver;
  int result = resolver.SetPacScriptFromDisk("international_domain_names.js");
  EXPECT_EQ(OK, result);

  // Execute FindProxyForURL().
  ProxyInfo proxy_info;
  result = resolver.GetProxyForURL(kQueryUrl, &proxy_info, NULL, NULL,
                                   BoundNetLog());

  EXPECT_EQ(OK, result);
  EXPECT_TRUE(proxy_info.is_direct());

  // Check that the international domain name was converted to punycode
  // before passing it onto the bindings layer.
  MockJSBindings* bindings = resolver.mock_js_bindings();

  ASSERT_EQ(1u, bindings->dns_resolves.size());
  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves[0]);

  ASSERT_EQ(1u, bindings->dns_resolves_ex.size());
  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]);
}

}  // namespace
}  // namespace net
