// 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 "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "mojo/common/common_type_converters.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 "third_party/mojo/src/mojo/public/cpp/bindings/binding.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_;

  ScopedVector<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(req.Pass());
}

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, action.proxy_servers.Pass());
      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(request.Pass(), dns_client.Pass());
      blocked_clients_.push_back(
          new interfaces::ProxyResolverRequestClientPtr(client.Pass()));
      break;
    }
  }
  WakeWaiter();
}

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

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

  int error() const { return error_; }
  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_;

  ScopedVector<interfaces::ProxyResolverFactoryRequestClientPtr>
      blocked_clients_;
  ScopedVector<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, req.Pass()) {
}

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(request.Pass());
      client->ReportResult(action.error);
      break;
    }
    case CreateProxyResolverAction::DROP_CLIENT: {
      // Save |request| so its pipe isn't closed.
      blocked_resolver_requests_.push_back(
          new mojo::InterfaceRequest<interfaces::ProxyResolver>(
              request.Pass()));
      break;
    }
    case CreateProxyResolverAction::DROP_RESOLVER: {
      // Save |client| so its pipe isn't closed.
      blocked_clients_.push_back(
          new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
      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(request.Pass(), dns_client.Pass());
      blocked_clients_.push_back(
          new interfaces::ProxyResolverFactoryRequestClientPtr(client.Pass()));
      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, req.Pass(), client.Pass());
    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_;
  scoped_ptr<ProxyResolver> proxy_resolver_mojo_;
  TestClosure on_delete_callback_;
};

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
