// 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 "services/network/proxy_resolver_factory_mojo.h"

#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task_runner.h"
#include "base/values.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/ip_address.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/base/network_isolation_key.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/pac_file_data.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/proxy_resolution/proxy_resolve_dns_operation.h"
#include "net/proxy_resolution/proxy_resolver.h"
#include "net/proxy_resolution/proxy_resolver_error_observer.h"
#include "services/network/mojo_host_resolver_impl.h"
#include "services/network/proxy_auto_config_library.h"
#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"

namespace net {
class NetworkIsolationKey;
}

namespace network {

namespace {

base::Value NetLogErrorParams(int line_number, const std::string& message) {
  base::DictionaryValue dict;
  dict.SetInteger("line_number", line_number);
  dict.SetString("message", message);
  return std::move(dict);
}

// Implementation for myIpAddress() and myIpAddressEx() that is expected to run
// on a worker thread. Will notify |client| on completion.
void DoMyIpAddressOnWorker(
    bool is_ex,
    mojo::PendingRemote<proxy_resolver::mojom::HostResolverRequestClient>
        client_remote) {
  // Resolve the list of IP addresses.
  std::vector<net::IPAddress> my_ip_addresses =
      is_ex ? PacMyIpAddressEx() : PacMyIpAddress();

  mojo::Remote<proxy_resolver::mojom::HostResolverRequestClient> client(
      std::move(client_remote));

  // TODO(eroman): Note that this code always returns a success response (with
  // loopback) rather than passing forward the error. This is to ensure that the
  // response gets cached on the proxy resolver process side, since this layer
  // here does not currently do any caching or de-duplication. This should be
  // cleaned up once the interfaces are refactored. Lastly note that for
  // myIpAddress() this doesn't change the final result. However for
  // myIpAddressEx() it means we return 127.0.0.1 rather than empty string.
  if (my_ip_addresses.empty())
    my_ip_addresses.push_back(net::IPAddress::IPv4Localhost());

  client->ReportResult(net::OK, my_ip_addresses);
}

// A mixin that forwards logging to (Bound)NetLog and ProxyResolverErrorObserver
// and DNS requests to a MojoHostResolverImpl, which is implemented in terms of
// a HostResolver, or myIpAddress[Ex]() which is implemented by //net.
template <typename ClientInterface>
class ClientMixin : public ClientInterface {
 public:
  ClientMixin(net::HostResolver* host_resolver,
              net::ProxyResolverErrorObserver* error_observer,
              net::NetLog* net_log,
              const net::NetLogWithSource& net_log_with_source)
      : host_resolver_(host_resolver, net_log_with_source),
        error_observer_(error_observer),
        net_log_(net_log),
        net_log_with_source_(net_log_with_source) {}

  // Overridden from ClientInterface:
  void Alert(const std::string& message) override {
    net_log_with_source_.AddEventWithStringParams(
        net::NetLogEventType::PAC_JAVASCRIPT_ALERT, "message", message);
    if (net_log_)
      net_log_->AddGlobalEntryWithStringParams(
          net::NetLogEventType::PAC_JAVASCRIPT_ALERT, "message", message);
  }

  void OnError(int32_t line_number, const std::string& message) override {
    net_log_with_source_.AddEvent(
        net::NetLogEventType::PAC_JAVASCRIPT_ERROR,
        [&] { return NetLogErrorParams(line_number, message); });
    if (net_log_)
      net_log_->AddGlobalEntry(net::NetLogEventType::PAC_JAVASCRIPT_ERROR, [&] {
        return NetLogErrorParams(line_number, message);
      });
    if (error_observer_) {
      error_observer_->OnPACScriptError(line_number,
                                        base::UTF8ToUTF16(message));
    }
  }

  // TODO(eroman): Split the client interfaces so ResolveDns() does not also
  // carry the myIpAddress(Ex) requests.
  void ResolveDns(
      const std::string& hostname,
      net::ProxyResolveDnsOperation operation,
      const net::NetworkIsolationKey& network_isolation_key,
      mojo::PendingRemote<proxy_resolver::mojom::HostResolverRequestClient>
          client) override {
    bool is_ex = operation == net::ProxyResolveDnsOperation::DNS_RESOLVE_EX ||
                 operation == net::ProxyResolveDnsOperation::MY_IP_ADDRESS_EX;

    if (operation == net::ProxyResolveDnsOperation::MY_IP_ADDRESS ||
        operation == net::ProxyResolveDnsOperation::MY_IP_ADDRESS_EX) {
      GetMyIpAddressTaskRuner()->PostTask(
          FROM_HERE,
          base::BindOnce(&DoMyIpAddressOnWorker, is_ex, std::move(client)));
    } else {
      // Request was for dnsResolve() or dnsResolveEx().
      host_resolver_.Resolve(hostname, network_isolation_key, is_ex,
                             std::move(client));
    }
  }

 protected:
  // TODO(eroman): This doesn't track being blocked in myIpAddress(Ex) handler.
  bool dns_request_in_progress() {
    return host_resolver_.request_in_progress();
  }

  // Returns a task runner used to run the code for myIpAddress[Ex].
  static scoped_refptr<base::TaskRunner> GetMyIpAddressTaskRuner() {
    // TODO(eroman): While these tasks are expected to normally run quickly,
    // it would be prudent to enforce a bound on outstanding tasks, and maybe
    // de-duplication of requests.
    //
    // However the better place to focus on is de-duplication and caching on the
    // proxy service side (which currently caches but doesn't de-duplicate).
    return base::CreateSequencedTaskRunner(
        {base::ThreadPool(), base::MayBlock(),
         base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
         base::TaskPriority::USER_VISIBLE});
  }

 private:
  MojoHostResolverImpl host_resolver_;
  net::ProxyResolverErrorObserver* const error_observer_;
  net::NetLog* const net_log_;
  const net::NetLogWithSource net_log_with_source_;
};

// Implementation of ProxyResolver that connects to a Mojo service to evaluate
// PAC scripts. This implementation only knows about Mojo services, and
// therefore that service may live in or out of process.
//
// This implementation reports disconnections from the Mojo service (i.e. if the
// service is out-of-process and that process crashes) using the error code
// ERR_PAC_SCRIPT_TERMINATED.
class ProxyResolverMojo : public net::ProxyResolver {
 public:
  // Constructs a ProxyResolverMojo that connects to a mojo proxy resolver
  // implementation using |resolver_remote|. The implementation uses
  // |host_resolver| as the DNS resolver, using |host_resolver_binding| to
  // communicate with it.
  ProxyResolverMojo(
      mojo::PendingRemote<proxy_resolver::mojom::ProxyResolver> resolver_remote,
      net::HostResolver* host_resolver,
      std::unique_ptr<net::ProxyResolverErrorObserver> error_observer,
      net::NetLog* net_log);
  ~ProxyResolverMojo() override;

  // ProxyResolver implementation:
  int GetProxyForURL(const GURL& url,
                     const net::NetworkIsolationKey& network_isolation_key,
                     net::ProxyInfo* results,
                     net::CompletionOnceCallback callback,
                     std::unique_ptr<Request>* request,
                     const net::NetLogWithSource& net_log) override;

 private:
  class Job;

  SEQUENCE_CHECKER(sequence_checker_);

  // Mojo disconnect handler.
  void OnMojoDisconnect();

  // Connection to the Mojo proxy resolver.
  mojo::Remote<proxy_resolver::mojom::ProxyResolver>
      mojo_proxy_resolver_remote_;

  net::HostResolver* host_resolver_;

  std::unique_ptr<net::ProxyResolverErrorObserver> error_observer_;

  net::NetLog* net_log_;

  DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo);
};

class ProxyResolverMojo::Job
    : public ProxyResolver::Request,
      public ClientMixin<proxy_resolver::mojom::ProxyResolverRequestClient> {
 public:
  Job(ProxyResolverMojo* resolver,
      const GURL& url,
      const net::NetworkIsolationKey& network_isolation_key,
      net::ProxyInfo* results,
      net::CompletionOnceCallback callback,
      const net::NetLogWithSource& net_log);
  ~Job() override;

  // Returns the LoadState of this job.
  net::LoadState GetLoadState() override;

 private:
  // Mojo disconnection handler.
  void OnMojoDisconnect();

  // Overridden from proxy_resolver::mojom::ProxyResolverRequestClient:
  void ReportResult(int32_t error, const net::ProxyInfo& proxy_info) override;

  // Completes a request with a result code.
  void CompleteRequest(int result);

  const GURL url_;
  net::ProxyInfo* results_;
  net::CompletionOnceCallback callback_;

  SEQUENCE_CHECKER(sequence_checker_);
  mojo::Receiver<proxy_resolver::mojom::ProxyResolverRequestClient> receiver_{
      this};

  DISALLOW_COPY_AND_ASSIGN(Job);
};

ProxyResolverMojo::Job::Job(
    ProxyResolverMojo* resolver,
    const GURL& url,
    const net::NetworkIsolationKey& network_isolation_key,
    net::ProxyInfo* results,
    net::CompletionOnceCallback callback,
    const net::NetLogWithSource& net_log)
    : ClientMixin<proxy_resolver::mojom::ProxyResolverRequestClient>(
          resolver->host_resolver_,
          resolver->error_observer_.get(),
          resolver->net_log_,
          net_log),
      url_(url),
      results_(results),
      callback_(std::move(callback)) {
  resolver->mojo_proxy_resolver_remote_->GetProxyForUrl(
      url_, network_isolation_key, receiver_.BindNewPipeAndPassRemote());
  receiver_.set_disconnect_handler(base::Bind(
      &ProxyResolverMojo::Job::OnMojoDisconnect, base::Unretained(this)));
}

ProxyResolverMojo::Job::~Job() {}

net::LoadState ProxyResolverMojo::Job::GetLoadState() {
  return dns_request_in_progress() ? net::LOAD_STATE_RESOLVING_HOST_IN_PAC_FILE
                                   : net::LOAD_STATE_RESOLVING_PROXY_FOR_URL;
}

void ProxyResolverMojo::Job::OnMojoDisconnect() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(1) << "ProxyResolverMojo::Job::OnMojoDisconnect";
  CompleteRequest(net::ERR_PAC_SCRIPT_TERMINATED);
}

void ProxyResolverMojo::Job::CompleteRequest(int result) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  net::CompletionOnceCallback callback = std::move(callback_);
  receiver_.reset();
  std::move(callback).Run(result);
}

void ProxyResolverMojo::Job::ReportResult(int32_t error,
                                          const net::ProxyInfo& proxy_info) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(1) << "ProxyResolverMojo::Job::ReportResult: " << error;

  if (error == net::OK) {
    *results_ = proxy_info;
    DVLOG(1) << "Servers: " << results_->ToPacString();
  }

  CompleteRequest(error);
}

ProxyResolverMojo::ProxyResolverMojo(
    mojo::PendingRemote<proxy_resolver::mojom::ProxyResolver> resolver_remote,
    net::HostResolver* host_resolver,
    std::unique_ptr<net::ProxyResolverErrorObserver> error_observer,
    net::NetLog* net_log)
    : mojo_proxy_resolver_remote_(std::move(resolver_remote)),
      host_resolver_(host_resolver),
      error_observer_(std::move(error_observer)),
      net_log_(net_log) {
  mojo_proxy_resolver_remote_.set_disconnect_handler(
      base::Bind(&ProxyResolverMojo::OnMojoDisconnect, base::Unretained(this)));
}

ProxyResolverMojo::~ProxyResolverMojo() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void ProxyResolverMojo::OnMojoDisconnect() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DVLOG(1) << "ProxyResolverMojo::OnMojoDisconnect";

  // Disconnect from the Mojo proxy resolver service.
  mojo_proxy_resolver_remote_.reset();
}

int ProxyResolverMojo::GetProxyForURL(
    const GURL& url,
    const net::NetworkIsolationKey& network_isolation_key,
    net::ProxyInfo* results,
    net::CompletionOnceCallback callback,
    std::unique_ptr<Request>* request,
    const net::NetLogWithSource& net_log) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!mojo_proxy_resolver_remote_)
    return net::ERR_PAC_SCRIPT_TERMINATED;

  *request = std::make_unique<Job>(this, url, network_isolation_key, results,
                                   std::move(callback), net_log);

  return net::ERR_IO_PENDING;
}

}  // namespace

// A Job to create a ProxyResolver instance.
//
// Note: a Job instance is not tied to a particular resolve request, and hence
// there is no per-request logging to be done (any netlog events are only sent
// globally) so this always uses an empty NetLogWithSource.
class ProxyResolverFactoryMojo::Job
    : public ClientMixin<
          proxy_resolver::mojom::ProxyResolverFactoryRequestClient>,
      public ProxyResolverFactory::Request {
 public:
  Job(ProxyResolverFactoryMojo* factory,
      const scoped_refptr<net::PacFileData>& pac_script,
      std::unique_ptr<net::ProxyResolver>* resolver,
      net::CompletionOnceCallback callback,
      std::unique_ptr<net::ProxyResolverErrorObserver> error_observer)
      : ClientMixin<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>(
            factory->host_resolver_,
            error_observer.get(),
            factory->net_log_,
            net::NetLogWithSource()),
        factory_(factory),
        resolver_(resolver),
        callback_(std::move(callback)),
        error_observer_(std::move(error_observer)) {
    factory_->mojo_proxy_factory_->CreateResolver(
        base::UTF16ToUTF8(pac_script->utf16()),
        resolver_remote_.InitWithNewPipeAndPassReceiver(),
        receiver_.BindNewPipeAndPassRemote());
    receiver_.set_disconnect_handler(
        base::Bind(&ProxyResolverFactoryMojo::Job::OnMojoDisconnect,
                   base::Unretained(this)));
  }

  void OnMojoDisconnect() { ReportResult(net::ERR_PAC_SCRIPT_TERMINATED); }

 private:
  void ReportResult(int32_t error) override {
    // Prevent any other messages arriving unexpectedly, in the case |this|
    // isn't destroyed immediately.
    receiver_.reset();

    if (error == net::OK) {
      *resolver_ = std::make_unique<ProxyResolverMojo>(
          std::move(resolver_remote_), factory_->host_resolver_,
          std::move(error_observer_), factory_->net_log_);
    }
    std::move(callback_).Run(error);
  }

  ProxyResolverFactoryMojo* const factory_;
  std::unique_ptr<net::ProxyResolver>* resolver_;
  net::CompletionOnceCallback callback_;
  mojo::PendingRemote<proxy_resolver::mojom::ProxyResolver> resolver_remote_;
  mojo::Receiver<proxy_resolver::mojom::ProxyResolverFactoryRequestClient>
      receiver_{this};
  std::unique_ptr<net::ProxyResolverErrorObserver> error_observer_;
};

ProxyResolverFactoryMojo::ProxyResolverFactoryMojo(
    mojo::PendingRemote<proxy_resolver::mojom::ProxyResolverFactory>
        mojo_proxy_factory,
    net::HostResolver* host_resolver,
    const base::Callback<std::unique_ptr<net::ProxyResolverErrorObserver>()>&
        error_observer_factory,
    net::NetLog* net_log)
    : ProxyResolverFactory(true),
      mojo_proxy_factory_(std::move(mojo_proxy_factory)),
      host_resolver_(host_resolver),
      error_observer_factory_(error_observer_factory),
      net_log_(net_log) {}

ProxyResolverFactoryMojo::~ProxyResolverFactoryMojo() = default;

int ProxyResolverFactoryMojo::CreateProxyResolver(
    const scoped_refptr<net::PacFileData>& pac_script,
    std::unique_ptr<net::ProxyResolver>* resolver,
    net::CompletionOnceCallback callback,
    std::unique_ptr<net::ProxyResolverFactory::Request>* request) {
  DCHECK(resolver);
  DCHECK(request);
  if (pac_script->type() != net::PacFileData::TYPE_SCRIPT_CONTENTS ||
      pac_script->utf16().empty()) {
    return net::ERR_PAC_SCRIPT_FAILED;
  }
  *request = std::make_unique<Job>(
      this, pac_script, resolver, std::move(callback),
      error_observer_factory_.is_null() ? nullptr
                                        : error_observer_factory_.Run());
  return net::ERR_IO_PENDING;
}

}  // namespace network
