// Copyright (c) 2010 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.

#define LOG_TAG "ProxyResolverTest"
#include <utils/Log.h>

#include <string.h>

#include <gtest/gtest.h>

#include "android_runtime/AndroidRuntime.h"
#include "proxy_test_script.h"
#include "proxy_resolver_v8.h"

using namespace android;
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 ProxyErrorListener {
 public:
  MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}

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

  virtual bool MyIpAddressEx(std::string* ip_address_list) {
    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) {
    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) {
    dns_resolves_ex.push_back(host);
    *ip_address_list = dns_resolve_ex_result;
    return !dns_resolve_ex_result.empty();
  }

  virtual void AlertMessage(String16 message) {
    String8 m8(message);
    std::string mstd(m8.string());

    ALOGD("PAC-alert: %s\n", mstd.c_str());  // Helpful when debugging.
    alerts.push_back(mstd);
  }

  virtual void ErrorMessage(const String16 message) {
    String8 m8(message);
    std::string mstd(m8.string());

    ALOGD("PAC-error: %s\n", mstd.c_str());  // Helpful when debugging.
    errors.push_back(mstd);
  }

  virtual void Shutdown() {}

  // 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<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(MockJSBindings* mock_js_bindings) :
      ProxyResolverV8(mock_js_bindings, mock_js_bindings), mock_js_bindings_(mock_js_bindings) {
  }

  MockJSBindings* mock_js_bindings() const {
    return mock_js_bindings_;
  }

 private:
  MockJSBindings* mock_js_bindings_;
};

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

String16 currentPac;
#define SCRIPT(x) (currentPac = String16(x))

void addString(std::vector<std::string>* list, std::string str) {
  if (str.compare(0, 6, "DIRECT") == 0) {
    list->push_back("DIRECT");
  } else if (str.compare(0, 6, "PROXY ") == 0) {
    list->push_back(str.substr(6));
  } else {
    ALOGE("Unrecognized proxy string");
  }
}

std::vector<std::string> string16ToProxyList(String16 response) {
    std::vector<std::string> ret;
    String8 response8(response);
    std::string rstr(response8.string());
    if (rstr.find(';') == std::string::npos) {
        addString(&ret, rstr);
        return ret;
    }
    char str[128];
    rstr.copy(str, 0, rstr.length());
    const char* pch = strtok(str, ";");

    while (pch != NULL) {
        // Skip leading whitespace
        while ((*pch) == ' ') ++pch;
        std::string pstring(pch);
        addString(&ret, pstring);

        pch = strtok(NULL, "; \t");
    }

    return ret;
}

std::string StringPrintf(std::string str, int d) {
    char buf[30];
    sprintf(buf, str.c_str(), d);
    return std::string(buf);
}

TEST(ProxyResolverV8Test, Direct) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(proxies.size(), 1U);
  EXPECT_EQ("DIRECT",proxies[0]);

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

TEST(ProxyResolverV8Test, ReturnEmptyString) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(RETURN_EMPTY_STRING_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(proxies.size(), 0U);

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

TEST(ProxyResolverV8Test, Basic) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(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().
  {
    String16 queryUrl("http://query.com/path");
    String16 queryHost("query.com");
    result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);
    EXPECT_EQ(OK, result);
    std::vector<std::string> proxies = string16ToProxyList(kResults);
    EXPECT_EQ(1U, proxies.size());
    EXPECT_EQ("http.query.com.path.query.com", proxies[0]);
  }
  {
    String16 queryUrl("ftp://query.com:90/path");
    String16 queryHost("query.com");
    int result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);

    EXPECT_EQ(OK, result);
    // Note that FindProxyForURL(url, host) does not expect |host| to contain
    // the port number.
    std::vector<std::string> proxies = string16ToProxyList(kResults);
    EXPECT_EQ(1U, proxies.size());
    EXPECT_EQ("ftp.query.com.90.path.query.com", proxies[0]);

    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 files of PAC scripts which each return a non-string
  // types for FindProxyForURL(). They should all fail with
  // ERR_PAC_SCRIPT_FAILED.
  static const String16 files[] = {
      String16(RETURN_UNDEFINED_JS),
      String16(RETURN_INTEGER_JS),
      String16(RETURN_FUNCTION_JS),
      String16(RETURN_OBJECT_JS),
      String16(RETURN_NULL_JS)
  };

  for (size_t i = 0; i < 5; ++i) {
    ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
    int result = resolver.SetPacScript(files[i]);
    EXPECT_EQ(OK, result);

    result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

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

// Try using a PAC script which defines no "FindProxyForURL" function.
TEST(ProxyResolverV8Test, NoEntryPoint) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(NO_ENTRYPOINT_JS));
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(ERR_FAILED, result);
}

// Try loading a malformed PAC script.
TEST(ProxyResolverV8Test, ParseError) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(MISSING_CLOSE_BRACE_JS));
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

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

// Run a PAC script several times, which has side-effects.
TEST(ProxyResolverV8Test, SideEffects) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(SIDE_EFFECTS_JS));

  // The PAC script increments a counter each time we invoke it.
  for (int i = 0; i < 3; ++i) {
    result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
    EXPECT_EQ(OK, result);
    std::vector<std::string> proxies = string16ToProxyList(kResults);
    EXPECT_EQ(1U, proxies.size());
    EXPECT_EQ(StringPrintf("sideffect_%d", i),
              proxies[0]);
  }

  // Reload the script -- the javascript environment should be reset, hence
  // the counter starts over.
  result = resolver.SetPacScript(SCRIPT(SIDE_EFFECTS_JS));
  EXPECT_EQ(OK, result);

  for (int i = 0; i < 3; ++i) {
    result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
    EXPECT_EQ(OK, result);
    std::vector<std::string> proxies = string16ToProxyList(kResults);
    EXPECT_EQ(1U, proxies.size());
    EXPECT_EQ(StringPrintf("sideffect_%d", i),
              proxies[0]);
  }
}

// Execute a PAC script which throws an exception in FindProxyForURL.
TEST(ProxyResolverV8Test, UnhandledException) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(UNHANDLED_EXCEPTION_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

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

TEST(ProxyResolverV8Test, ReturnUnicode) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(RETURN_UNICODE_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  // 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) {
  ALOGE("Javascript start");
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(PAC_LIBRARY_UNITTEST_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  // 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);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_EQ("success:80", proxies[0]);

  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(new MockJSBindings());


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

  // Initialize it.
  result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
  EXPECT_EQ(OK, result);

  // Resolve should now succeed.
  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
  EXPECT_EQ(OK, result);

  // Clear it, by initializing with an empty string.
  resolver.SetPacScript(SCRIPT());

  // Resolve should fail again now.
  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
  EXPECT_EQ(ERR_FAILED, result);

  // Load a good script once more.
  result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
  EXPECT_EQ(OK, result);
  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
  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(new MockJSBindings());
  MockJSBindings* bindings = resolver.mock_js_bindings();
  bindings->dns_resolve_result = "127.0.0.1";
  int result = resolver.SetPacScript(SCRIPT(BINDINGS_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_EQ("DIRECT", proxies[0]);

  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(new MockJSBindings());

  int result = resolver.SetPacScript(SCRIPT(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);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_NE("DIRECT", proxies[0]);
  EXPECT_EQ("127.0.0.1:80", proxies[0]);

  // 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(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(ENDS_WITH_COMMENT_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_NE("DIRECT", proxies[0]);
  EXPECT_EQ("success:80", proxies[0]);
}

// 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(new MockJSBindings());
  int result = resolver.SetPacScript(
      SCRIPT(ENDS_WITH_STATEMENT_NO_SEMICOLON_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_NE("DIRECT", proxies[0]);
  EXPECT_EQ("success:3", proxies[0]);
}

// 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(new MockJSBindings());
  int result = resolver.SetPacScript(SCRIPT(DNS_FAIL_JS));
  EXPECT_EQ(OK, result);

  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_NE("DIRECT", proxies[0]);
  EXPECT_EQ("success:80", proxies[0]);
}

TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
    return;
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(String16(INTERNATIONAL_DOMAIN_NAMES_JS));
  EXPECT_EQ(OK, result);

  // Execute FindProxyForURL().
  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_EQ("DIRECT", proxies[0]);

  // 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]);
}

TEST(ProxyResolverV8Test, GetterChangesElementKind) {
  ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
  int result = resolver.SetPacScript(String16(CHANGE_ELEMENT_KIND_JS));
  EXPECT_EQ(OK, result);

  // Execute FindProxyForURL().
  result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);

  EXPECT_EQ(OK, result);
  std::vector<std::string> proxies = string16ToProxyList(kResults);
  EXPECT_EQ(1U, proxies.size());
  EXPECT_EQ("DIRECT", proxies[0]);
}

}  // namespace
}  // namespace net
