// Copyright 2015 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 "net/proxy/proxy_resolver_factory_mojo.h"

#include <list>
#include <map>
#include <queue>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/host_resolver.h"
#include "net/log/test_net_log.h"
#include "net/proxy/mojo_proxy_resolver_factory.h"
#include "net/proxy/mojo_proxy_type_converters.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_resolver_error_observer.h"
#include "net/proxy/proxy_resolver_script_data.h"
#include "net/test/event_waiter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

namespace {

const char kScriptData[] = "FooBarBaz";
const char kExampleUrl[] = "http://www.example.com";

struct CreateProxyResolverAction {
  enum Action {
    COMPLETE,
    DROP_CLIENT,
    DROP_RESOLVER,
    DROP_BOTH,
    WAIT_FOR_CLIENT_DISCONNECT,
    MAKE_DNS_REQUEST,
  };

  static CreateProxyResolverAction ReturnResult(
      const std::string& expected_pac_script,
      Error error) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.error = error;
    return result;
  }

  static CreateProxyResolverAction DropClient(
      const std::string& expected_pac_script) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.action = DROP_CLIENT;
    return result;
  }

  static CreateProxyResolverAction DropResolver(
      const std::string& expected_pac_script) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.action = DROP_RESOLVER;
    return result;
  }

  static CreateProxyResolverAction DropBoth(
      const std::string& expected_pac_script) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.action = DROP_BOTH;
    return result;
  }

  static CreateProxyResolverAction WaitForClientDisconnect(
      const std::string& expected_pac_script) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.action = WAIT_FOR_CLIENT_DISCONNECT;
    return result;
  }

  static CreateProxyResolverAction MakeDnsRequest(
      const std::string& expected_pac_script) {
    CreateProxyResolverAction result;
    result.expected_pac_script = expected_pac_script;
    result.action = MAKE_DNS_REQUEST;
    return result;
  }

  std::string expected_pac_script;
  Action action = COMPLETE;
  Error error = OK;
};

struct GetProxyForUrlAction {
  enum Action {
    COMPLETE,
    // Drop the request by closing the reply channel.
    DROP,
    // Disconnect the service.
    DISCONNECT,
    // Wait for the client pipe to be disconnected.
    WAIT_FOR_CLIENT_DISCONNECT,
    // Make a DNS request.
    MAKE_DNS_REQUEST,
  };

  GetProxyForUrlAction() {}
  GetProxyForUrlAction(const GetProxyForUrlAction& old) {
    action = old.action;
    error = old.error;
    expected_url = old.expected_url;
    proxy_servers = old.proxy_servers.Clone();
  }

  static GetProxyForUrlAction ReturnError(const GURL& url, Error error) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.error = error;
    return result;
  }

  static GetProxyForUrlAction ReturnServers(
      const GURL& url,
      const mojo::Array<interfaces::ProxyServerPtr>& proxy_servers) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.proxy_servers = proxy_servers.Clone();
    return result;
  }

  static GetProxyForUrlAction DropRequest(const GURL& url) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.action = DROP;
    return result;
  }

  static GetProxyForUrlAction Disconnect(const GURL& url) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.action = DISCONNECT;
    return result;
  }

  static GetProxyForUrlAction WaitForClientDisconnect(const GURL& url) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.action = WAIT_FOR_CLIENT_DISCONNECT;
    return result;
  }

  static GetProxyForUrlAction MakeDnsRequest(const GURL& url) {
    GetProxyForUrlAction result;
    result.expected_url = url;
    result.action = MAKE_DNS_REQUEST;
    return result;
  }

  Action action = COMPLETE;
  Error error = OK;
  mojo::Array<interfaces::ProxyServerPtr> proxy_servers;
  GURL expected_url;
};

class MockMojoProxyResolver : public interfaces::ProxyResolver {
 public:
  MockMojoProxyResolver();
  ~MockMojoProxyResolver() override;

  void AddGetProxyAction(GetProxyForUrlAction action);

  void WaitForNextRequest();

  void ClearBlockedClients();

  void AddConnection(mojo::InterfaceRequest<interfaces::ProxyResolver> req);

 private:
  // Overridden from interfaces::ProxyResolver:
  void GetProxyForUrl(
      const mojo::String& url,
      interfaces::ProxyResolverRequestClientPtr client) override;

  void WakeWaiter();

  std::string pac_script_data_;

  std::queue<GetProxyForUrlAction> get_proxy_actions_;

  base::Closure quit_closure_;

  std::vector<scoped_ptr<interfaces::ProxyResolverRequestClientPtr>>
      blocked_clients_;
  mojo::Binding<interfaces::ProxyResolver> binding_;
};

MockMojoProxyResolver::~MockMojoProxyResolver() {
  EXPECT_TRUE(get_proxy_actions_.empty())
      << "Actions remaining: " << get_proxy_actions_.size();
}

MockMojoProxyResolver::MockMojoProxyResolver() : binding_(this) {
}

void MockMojoProxyResolver::AddGetProxyAction(GetProxyForUrlAction action) {
  get_proxy_actions_.push(action);
}

void MockMojoProxyResolver::WaitForNextRequest() {
  base::RunLoop run_loop;
  quit_closure_ = run_loop.QuitClosure();
  run_loop.Run();
}

void MockMojoProxyResolver::WakeWaiter() {
  if (!quit_closure_.is_null())
    quit_closure_.Run();
  quit_closure_.Reset();
}

void MockMojoProxyResolver::ClearBlockedClients() {
  blocked_clients_.clear();
}

void MockMojoProxyResolver::AddConnection(
    mojo::InterfaceRequest<interfaces::ProxyResolver> req) {
  if (binding_.is_bound())
    binding_.Close();
  binding_.Bind(std::move(req));
}

void MockMojoProxyResolver::GetProxyForUrl(
    const mojo::String& url,
    interfaces::ProxyResolverRequestClientPtr client) {
  ASSERT_FALSE(get_proxy_actions_.empty());
  GetProxyForUrlAction action = get_proxy_actions_.front();
  get_proxy_actions_.pop();

  EXPECT_EQ(action.expected_url.spec(), url.To<std::string>());
  client->Alert(url);
  client->OnError(12345, url);
  switch (action.action) {
    case GetProxyForUrlAction::COMPLETE: {
      client->ReportResult(action.error, std::move(action.proxy_servers));
      break;
    }
    case GetProxyForUrlAction::DROP: {
      client.reset();
      break;
    }
    case GetProxyForUrlAction::DISCONNECT: {
      binding_.Close();
      break;
    }
    case GetProxyForUrlAction::WAIT_FOR_CLIENT_DISCONNECT: {
      ASSERT_FALSE(client.WaitForIncomingResponse());
      break;
    }
    case GetProxyForUrlAction::MAKE_DNS_REQUEST: {
      interfaces::HostResolverRequestInfoPtr request(
          interfaces::HostResolverRequestInfo::New());
      request->host = url;
      request->port = 12345;
      interfaces::HostResolverRequestClientPtr dns_client;
      mojo::GetProxy(&dns_client);
      client->ResolveDns(std::move(request), std::move(dns_client));
      blocked_clients_.push_back(make_scoped_ptr(
          new interfaces::ProxyResolverRequestClientPtr(std::move(client))));
      break;
    }
  }
  WakeWaiter();
}

class Request {
 public:
  Request(ProxyResolver* resolver, const GURL& url);

  int Resolve();
  void Cancel();
  int WaitForResult();

  const ProxyInfo& results() const { return results_; }
  LoadState load_state() { return resolver_->GetLoadState(handle_); }
  BoundTestNetLog& net_log() { return net_log_; }

 private:
  ProxyResolver* resolver_;
  const GURL url_;
  ProxyInfo results_;
  ProxyResolver::RequestHandle handle_;
  int error_;
  TestCompletionCallback callback_;
  BoundTestNetLog net_log_;
};

Request::Request(ProxyResolver* resolver, const GURL& url)
    : resolver_(resolver), url_(url), error_(0) {
}

int Request::Resolve() {
  error_ = resolver_->GetProxyForURL(url_, &results_, callback_.callback(),
                                     &handle_, net_log_.bound());
  return error_;
}

void Request::Cancel() {
  resolver_->CancelRequest(handle_);
}

int Request::WaitForResult() {
  error_ = callback_.WaitForResult();
  return error_;
}

class MockMojoProxyResolverFactory : public interfaces::ProxyResolverFactory {
 public:
  MockMojoProxyResolverFactory(
      MockMojoProxyResolver* resolver,
      mojo::InterfaceRequest<interfaces::ProxyResolverFactory> req);
  ~MockMojoProxyResolverFactory() override;

  void AddCreateProxyResolverAction(CreateProxyResolverAction action);

  void WaitForNextRequest();

  void ClearBlockedClients();

 private:
  // Overridden from interfaces::ProxyResolver:
  void CreateResolver(
      const mojo::String& pac_url,
      mojo::InterfaceRequest<interfaces::ProxyResolver> request,
      interfaces::ProxyResolverFactoryRequestClientPtr client) override;

  void WakeWaiter();

  MockMojoProxyResolver* resolver_;
  std::queue<CreateProxyResolverAction> create_resolver_actions_;

  base::Closure quit_closure_;

  std::vector<scoped_ptr<interfaces::ProxyResolverFactoryRequestClientPtr>>
      blocked_clients_;
  std::vector<scoped_ptr<mojo::InterfaceRequest<interfaces::ProxyResolver>>>
      blocked_resolver_requests_;
  mojo::Binding<interfaces::ProxyResolverFactory> binding_;
};

MockMojoProxyResolverFactory::MockMojoProxyResolverFactory(
    MockMojoProxyResolver* resolver,
    mojo::InterfaceRequest<interfaces::ProxyResolverFactory> req)
    : resolver_(resolver), binding_(this, std::move(req)) {}

MockMojoProxyResolverFactory::~MockMojoProxyResolverFactory() {
  EXPECT_TRUE(create_resolver_actions_.empty())
      << "Actions remaining: " << create_resolver_actions_.size();
}

void MockMojoProxyResolverFactory::AddCreateProxyResolverAction(
    CreateProxyResolverAction action) {
  create_resolver_actions_.push(action);
}

void MockMojoProxyResolverFactory::WaitForNextRequest() {
  base::RunLoop run_loop;
  quit_closure_ = run_loop.QuitClosure();
  run_loop.Run();
}

void MockMojoProxyResolverFactory::WakeWaiter() {
  if (!quit_closure_.is_null())
    quit_closure_.Run();
  quit_closure_.Reset();
}

void MockMojoProxyResolverFactory::ClearBlockedClients() {
  blocked_clients_.clear();
}

void MockMojoProxyResolverFactory::CreateResolver(
    const mojo::String& pac_script,
    mojo::InterfaceRequest<interfaces::ProxyResolver> request,
    interfaces::ProxyResolverFactoryRequestClientPtr client) {
  ASSERT_FALSE(create_resolver_actions_.empty());
  CreateProxyResolverAction action = create_resolver_actions_.front();
  create_resolver_actions_.pop();

  EXPECT_EQ(action.expected_pac_script, pac_script.To<std::string>());
  client->Alert(pac_script);
  client->OnError(12345, pac_script);
  switch (action.action) {
    case CreateProxyResolverAction::COMPLETE: {
      if (action.error == OK)
        resolver_->AddConnection(std::move(request));
      client->ReportResult(action.error);
      break;
    }
    case CreateProxyResolverAction::DROP_CLIENT: {
      // Save |request| so its pipe isn't closed.
      blocked_resolver_requests_.push_back(
          make_scoped_ptr(new mojo::InterfaceRequest<interfaces::ProxyResolver>(
              std::move(request))));
      break;
    }
    case CreateProxyResolverAction::DROP_RESOLVER: {
      // Save |client| so its pipe isn't closed.
      blocked_clients_.push_back(
          make_scoped_ptr(new interfaces::ProxyResolverFactoryRequestClientPtr(
              std::move(client))));
      break;
    }
    case CreateProxyResolverAction::DROP_BOTH: {
      // Both |request| and |client| will be closed.
      break;
    }
    case CreateProxyResolverAction::WAIT_FOR_CLIENT_DISCONNECT: {
      ASSERT_FALSE(client.WaitForIncomingResponse());
      break;
    }
    case CreateProxyResolverAction::MAKE_DNS_REQUEST: {
      interfaces::HostResolverRequestInfoPtr request(
          interfaces::HostResolverRequestInfo::New());
      request->host = pac_script;
      request->port = 12345;
      interfaces::HostResolverRequestClientPtr dns_client;
      mojo::GetProxy(&dns_client);
      client->ResolveDns(std::move(request), std::move(dns_client));
      blocked_clients_.push_back(
          make_scoped_ptr(new interfaces::ProxyResolverFactoryRequestClientPtr(
              std::move(client))));
      break;
    }
  }
  WakeWaiter();
}

void DeleteResolverFactoryRequestCallback(
    scoped_ptr<ProxyResolverFactory::Request>* request,
    const CompletionCallback& callback,
    int result) {
  ASSERT_TRUE(request);
  EXPECT_TRUE(request->get());
  request->reset();
  callback.Run(result);
}

class MockHostResolver : public HostResolver {
 public:
  enum Event {
    DNS_REQUEST,
  };

  // HostResolver overrides.
  int Resolve(const RequestInfo& info,
              RequestPriority priority,
              AddressList* addresses,
              const CompletionCallback& callback,
              RequestHandle* request_handle,
              const BoundNetLog& source_net_log) override {
    waiter_.NotifyEvent(DNS_REQUEST);
    return ERR_IO_PENDING;
  }
  int ResolveFromCache(const RequestInfo& info,
                       AddressList* addresses,
                       const BoundNetLog& source_net_log) override {
    return ERR_DNS_CACHE_MISS;
  }
  void CancelRequest(RequestHandle req) override {}
  HostCache* GetHostCache() override { return nullptr; }

  EventWaiter<Event>& waiter() { return waiter_; }

 private:
  EventWaiter<Event> waiter_;
};

void CheckCapturedNetLogEntries(const std::string& expected_string,
                                const TestNetLogEntry::List& entries) {
  ASSERT_EQ(2u, entries.size());
  EXPECT_EQ(NetLog::TYPE_PAC_JAVASCRIPT_ALERT, entries[0].type);
  std::string message;
  ASSERT_TRUE(entries[0].GetStringValue("message", &message));
  EXPECT_EQ(expected_string, message);
  ASSERT_FALSE(entries[0].params->HasKey("line_number"));
  message.clear();
  EXPECT_EQ(NetLog::TYPE_PAC_JAVASCRIPT_ERROR, entries[1].type);
  ASSERT_TRUE(entries[1].GetStringValue("message", &message));
  EXPECT_EQ(expected_string, message);
  int line_number = 0;
  ASSERT_TRUE(entries[1].GetIntegerValue("line_number", &line_number));
  EXPECT_EQ(12345, line_number);
}

}  // namespace

class ProxyResolverFactoryMojoTest : public testing::Test,
                                     public MojoProxyResolverFactory {
 public:
  void SetUp() override {
    mock_proxy_resolver_factory_.reset(new MockMojoProxyResolverFactory(
        &mock_proxy_resolver_, mojo::GetProxy(&factory_ptr_)));
    proxy_resolver_factory_mojo_.reset(new ProxyResolverFactoryMojo(
        this, &host_resolver_,
        base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>(), &net_log_));
  }

  scoped_ptr<Request> MakeRequest(const GURL& url) {
    return make_scoped_ptr(new Request(proxy_resolver_mojo_.get(), url));
  }

  scoped_ptr<base::ScopedClosureRunner> CreateResolver(
      const mojo::String& pac_script,
      mojo::InterfaceRequest<interfaces::ProxyResolver> req,
      interfaces::ProxyResolverFactoryRequestClientPtr client) override {
    factory_ptr_->CreateResolver(pac_script, std::move(req), std::move(client));
    return make_scoped_ptr(
        new base::ScopedClosureRunner(on_delete_callback_.closure()));
  }

  mojo::Array<interfaces::ProxyServerPtr> ProxyServersFromPacString(
      const std::string& pac_string) {
    ProxyInfo proxy_info;
    proxy_info.UsePacString(pac_string);

    return mojo::Array<interfaces::ProxyServerPtr>::From(
        proxy_info.proxy_list().GetAll());
  }

  void CreateProxyResolver() {
    mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
        CreateProxyResolverAction::ReturnResult(kScriptData, OK));
    TestCompletionCallback callback;
    scoped_refptr<ProxyResolverScriptData> pac_script(
        ProxyResolverScriptData::FromUTF8(kScriptData));
    scoped_ptr<ProxyResolverFactory::Request> request;
    ASSERT_EQ(
        OK,
        callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
            pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
    EXPECT_TRUE(request);
    ASSERT_TRUE(proxy_resolver_mojo_);
  }

  void DeleteProxyResolverCallback(const CompletionCallback& callback,
                                   int result) {
    proxy_resolver_mojo_.reset();
    callback.Run(result);
  }

  MockHostResolver host_resolver_;
  TestNetLog net_log_;
  scoped_ptr<MockMojoProxyResolverFactory> mock_proxy_resolver_factory_;
  interfaces::ProxyResolverFactoryPtr factory_ptr_;
  scoped_ptr<ProxyResolverFactory> proxy_resolver_factory_mojo_;

  MockMojoProxyResolver mock_proxy_resolver_;
  TestClosure on_delete_callback_;
  scoped_ptr<ProxyResolver> proxy_resolver_mojo_;
};

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver) {
  CreateProxyResolver();
  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  CheckCapturedNetLogEntries(kScriptData, entries);
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Empty) {
  TestCompletionCallback callback;
  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(""));
  scoped_ptr<ProxyResolverFactory::Request> request;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_FAILED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_FALSE(request);
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Url) {
  TestCompletionCallback callback;
  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromURL(GURL(kExampleUrl)));
  scoped_ptr<ProxyResolverFactory::Request> request;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_FAILED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_FALSE(request);
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Failed) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::ReturnResult(kScriptData,
                                              ERR_PAC_STATUS_NOT_OK));

  TestCompletionCallback callback;
  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  EXPECT_EQ(
      ERR_PAC_STATUS_NOT_OK,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_TRUE(request);
  on_delete_callback_.WaitForResult();

  // A second attempt succeeds.
  CreateProxyResolver();
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_BothDisconnected) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::DropBoth(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_TERMINATED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_TRUE(request);
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_ClientDisconnected) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::DropClient(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_TERMINATED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_TRUE(request);
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_ResolverDisconnected) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::DropResolver(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_TERMINATED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_, callback.callback(), &request)));
  EXPECT_TRUE(request);
  on_delete_callback_.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest,
       CreateProxyResolver_ResolverDisconnected_DeleteRequestInCallback) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::DropResolver(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_TERMINATED,
      callback.GetResult(proxy_resolver_factory_mojo_->CreateProxyResolver(
          pac_script, &proxy_resolver_mojo_,
          base::Bind(&DeleteResolverFactoryRequestCallback, &request,
                     callback.callback()),
          &request)));
  on_delete_callback_.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_Cancel) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::WaitForClientDisconnect(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_factory_mojo_->CreateProxyResolver(
                                pac_script, &proxy_resolver_mojo_,
                                callback.callback(), &request));
  ASSERT_TRUE(request);
  request.reset();

  // The Mojo request is still made.
  mock_proxy_resolver_factory_->WaitForNextRequest();
  on_delete_callback_.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest, CreateProxyResolver_DnsRequest) {
  mock_proxy_resolver_factory_->AddCreateProxyResolverAction(
      CreateProxyResolverAction::MakeDnsRequest(kScriptData));

  scoped_refptr<ProxyResolverScriptData> pac_script(
      ProxyResolverScriptData::FromUTF8(kScriptData));
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_factory_mojo_->CreateProxyResolver(
                                pac_script, &proxy_resolver_mojo_,
                                callback.callback(), &request));
  ASSERT_TRUE(request);
  host_resolver_.waiter().WaitForEvent(MockHostResolver::DNS_REQUEST);
  mock_proxy_resolver_factory_->ClearBlockedClients();
  callback.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL) {
  const GURL url(kExampleUrl);
  mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
      url, ProxyServersFromPacString("DIRECT")));
  CreateProxyResolver();
  net_log_.Clear();

  scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
  EXPECT_EQ(OK, request->WaitForResult());

  EXPECT_EQ("DIRECT", request->results().ToPacString());

  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  CheckCapturedNetLogEntries(url.spec(), entries);
  entries.clear();
  request->net_log().GetEntries(&entries);
  CheckCapturedNetLogEntries(url.spec(), entries);
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_MultipleResults) {
  static const char kPacString[] =
      "PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
      "SOCKS5 foo3:1080;HTTPS foo4:443;QUIC foo6:8888";
  mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
      GURL(kExampleUrl), ProxyServersFromPacString(kPacString)));
  CreateProxyResolver();

  scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
  EXPECT_EQ(OK, request->WaitForResult());

  EXPECT_EQ(kPacString, request->results().ToPacString());
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Error) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::ReturnError(GURL(kExampleUrl), ERR_UNEXPECTED));
  CreateProxyResolver();

  scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
  EXPECT_EQ(ERR_UNEXPECTED, request->WaitForResult());

  EXPECT_TRUE(request->results().is_empty());
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Cancel) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::WaitForClientDisconnect(GURL(kExampleUrl)));
  CreateProxyResolver();

  scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
  request->Cancel();

  // The Mojo request is still made.
  mock_proxy_resolver_.WaitForNextRequest();
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_MultipleRequests) {
  mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
      GURL(kExampleUrl), ProxyServersFromPacString("DIRECT")));
  mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
      GURL("https://www.chromium.org"),
      ProxyServersFromPacString("HTTPS foo:443")));
  CreateProxyResolver();

  scoped_ptr<Request> request1(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request1->Resolve());
  scoped_ptr<Request> request2(MakeRequest(GURL("https://www.chromium.org")));
  EXPECT_EQ(ERR_IO_PENDING, request2->Resolve());

  EXPECT_EQ(OK, request1->WaitForResult());
  EXPECT_EQ(OK, request2->WaitForResult());

  EXPECT_EQ("DIRECT", request1->results().ToPacString());
  EXPECT_EQ("HTTPS foo:443", request2->results().ToPacString());
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_Disconnect) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::Disconnect(GURL(kExampleUrl)));
  CreateProxyResolver();
  {
    scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
    EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
    EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request->WaitForResult());
    EXPECT_TRUE(request->results().is_empty());
  }

  {
    // Calling GetProxyForURL after a disconnect should fail.
    scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
    EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request->Resolve());
  }
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_ClientClosed) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::DropRequest(GURL(kExampleUrl)));
  CreateProxyResolver();

  scoped_ptr<Request> request1(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request1->Resolve());

  EXPECT_EQ(ERR_PAC_SCRIPT_TERMINATED, request1->WaitForResult());
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DeleteInCallback) {
  mock_proxy_resolver_.AddGetProxyAction(GetProxyForUrlAction::ReturnServers(
      GURL(kExampleUrl), ProxyServersFromPacString("DIRECT")));
  CreateProxyResolver();

  ProxyInfo results;
  TestCompletionCallback callback;
  ProxyResolver::RequestHandle handle;
  BoundNetLog net_log;
  EXPECT_EQ(
      OK,
      callback.GetResult(proxy_resolver_mojo_->GetProxyForURL(
          GURL(kExampleUrl), &results,
          base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
                     base::Unretained(this), callback.callback()),
          &handle, net_log)));
  on_delete_callback_.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest,
       GetProxyForURL_DeleteInCallbackFromDisconnect) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::Disconnect(GURL(kExampleUrl)));
  CreateProxyResolver();

  ProxyInfo results;
  TestCompletionCallback callback;
  ProxyResolver::RequestHandle handle;
  BoundNetLog net_log;
  EXPECT_EQ(
      ERR_PAC_SCRIPT_TERMINATED,
      callback.GetResult(proxy_resolver_mojo_->GetProxyForURL(
          GURL(kExampleUrl), &results,
          base::Bind(&ProxyResolverFactoryMojoTest::DeleteProxyResolverCallback,
                     base::Unretained(this), callback.callback()),
          &handle, net_log)));
  on_delete_callback_.WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest, GetProxyForURL_DnsRequest) {
  mock_proxy_resolver_.AddGetProxyAction(
      GetProxyForUrlAction::MakeDnsRequest(GURL(kExampleUrl)));
  CreateProxyResolver();

  scoped_ptr<Request> request(MakeRequest(GURL(kExampleUrl)));
  EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
  EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL, request->load_state());

  host_resolver_.waiter().WaitForEvent(MockHostResolver::DNS_REQUEST);
  EXPECT_EQ(LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT, request->load_state());
  mock_proxy_resolver_.ClearBlockedClients();
  request->WaitForResult();
}

TEST_F(ProxyResolverFactoryMojoTest, DeleteResolver) {
  CreateProxyResolver();
  proxy_resolver_mojo_.reset();
  on_delete_callback_.WaitForResult();
}
}  // namespace net
