// 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 <set>

#include "base/bind.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/common/url_type_converters.h"
#include "net/base/load_states.h"
#include "net/base/net_errors.h"
#include "net/dns/mojo_host_resolver_impl.h"
#include "net/interfaces/host_resolver_service.mojom.h"
#include "net/interfaces/proxy_resolver_service.mojom.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 "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"

namespace net {
namespace {

scoped_ptr<base::Value> NetLogErrorCallback(
    int line_number,
    const base::string16* message,
    NetLogCaptureMode /* capture_mode */) {
  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
  dict->SetInteger("line_number", line_number);
  dict->SetString("message", *message);
  return dict.Pass();
}

// A mixin that forwards logging to (Bound)NetLog and ProxyResolverErrorObserver
// and DNS requests to a MojoHostResolverImpl, which is implemented in terms of
// a HostResolver.
template <typename ClientInterface>
class ClientMixin : public ClientInterface {
 public:
  ClientMixin(HostResolver* host_resolver,
              ProxyResolverErrorObserver* error_observer,
              NetLog* net_log,
              const BoundNetLog& bound_net_log)
      : host_resolver_(host_resolver, bound_net_log),
        error_observer_(error_observer),
        net_log_(net_log),
        bound_net_log_(bound_net_log) {}

  // Overridden from ClientInterface:
  void Alert(const mojo::String& message) override {
    base::string16 message_str = message.To<base::string16>();
    auto callback = NetLog::StringCallback("message", &message_str);
    bound_net_log_.AddEvent(NetLog::TYPE_PAC_JAVASCRIPT_ALERT, callback);
    if (net_log_)
      net_log_->AddGlobalEntry(NetLog::TYPE_PAC_JAVASCRIPT_ALERT, callback);
  }

  void OnError(int32_t line_number, const mojo::String& message) override {
    base::string16 message_str = message.To<base::string16>();
    auto callback = base::Bind(&NetLogErrorCallback, line_number, &message_str);
    bound_net_log_.AddEvent(NetLog::TYPE_PAC_JAVASCRIPT_ERROR, callback);
    if (net_log_)
      net_log_->AddGlobalEntry(NetLog::TYPE_PAC_JAVASCRIPT_ERROR, callback);
    if (error_observer_)
      error_observer_->OnPACScriptError(line_number, message_str);
  }

  void ResolveDns(interfaces::HostResolverRequestInfoPtr request_info,
                  interfaces::HostResolverRequestClientPtr client) override {
    host_resolver_.Resolve(request_info.Pass(), client.Pass());
  }

 protected:
  bool dns_request_in_progress() {
    return host_resolver_.request_in_progress();
  }

 private:
  MojoHostResolverImpl host_resolver_;
  ProxyResolverErrorObserver* const error_observer_;
  NetLog* const net_log_;
  const BoundNetLog bound_net_log_;
};

// 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 ProxyResolver {
 public:
  // Constructs a ProxyResolverMojo that connects to a mojo proxy resolver
  // implementation using |resolver_ptr|. The implementation uses
  // |host_resolver| as the DNS resolver, using |host_resolver_binding| to
  // communicate with it. When deleted, the closure contained within
  // |on_delete_callback_runner| will be run.
  ProxyResolverMojo(
      interfaces::ProxyResolverPtr resolver_ptr,
      HostResolver* host_resolver,
      scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner,
      scoped_ptr<ProxyResolverErrorObserver> error_observer,
      NetLog* net_log);
  ~ProxyResolverMojo() override;

  // ProxyResolver implementation:
  int GetProxyForURL(const GURL& url,
                     ProxyInfo* results,
                     const net::CompletionCallback& callback,
                     RequestHandle* request,
                     const BoundNetLog& net_log) override;
  void CancelRequest(RequestHandle request) override;
  LoadState GetLoadState(RequestHandle request) const override;

 private:
  class Job;

  // Mojo error handler.
  void OnConnectionError();

  void RemoveJob(Job* job);

  // Connection to the Mojo proxy resolver.
  interfaces::ProxyResolverPtr mojo_proxy_resolver_ptr_;

  HostResolver* host_resolver_;

  scoped_ptr<ProxyResolverErrorObserver> error_observer_;

  NetLog* net_log_;

  std::set<Job*> pending_jobs_;

  base::ThreadChecker thread_checker_;

  scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_;

  DISALLOW_COPY_AND_ASSIGN(ProxyResolverMojo);
};

class ProxyResolverMojo::Job
    : public ClientMixin<interfaces::ProxyResolverRequestClient> {
 public:
  Job(ProxyResolverMojo* resolver,
      const GURL& url,
      ProxyInfo* results,
      const CompletionCallback& callback,
      const BoundNetLog& net_log);
  ~Job() override;

  // Cancels the job and prevents the callback from being run.
  void Cancel();

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

 private:
  // Mojo error handler.
  void OnConnectionError();

  // Overridden from interfaces::ProxyResolverRequestClient:
  void ReportResult(
      int32_t error,
      mojo::Array<interfaces::ProxyServerPtr> proxy_servers) override;

  ProxyResolverMojo* resolver_;
  const GURL url_;
  ProxyInfo* results_;
  CompletionCallback callback_;

  base::ThreadChecker thread_checker_;
  mojo::Binding<interfaces::ProxyResolverRequestClient> binding_;
};

ProxyResolverMojo::Job::Job(ProxyResolverMojo* resolver,
                            const GURL& url,
                            ProxyInfo* results,
                            const CompletionCallback& callback,
                            const BoundNetLog& net_log)
    : ClientMixin<interfaces::ProxyResolverRequestClient>(
          resolver->host_resolver_,
          resolver->error_observer_.get(),
          resolver->net_log_,
          net_log),
      resolver_(resolver),
      url_(url),
      results_(results),
      callback_(callback),
      binding_(this) {
  binding_.set_connection_error_handler(base::Bind(
      &ProxyResolverMojo::Job::OnConnectionError, base::Unretained(this)));

  interfaces::ProxyResolverRequestClientPtr client_ptr;
  binding_.Bind(mojo::GetProxy(&client_ptr));
  resolver_->mojo_proxy_resolver_ptr_->GetProxyForUrl(mojo::String::From(url_),
                                                      client_ptr.Pass());
}

ProxyResolverMojo::Job::~Job() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (!callback_.is_null())
    callback_.Run(ERR_PAC_SCRIPT_TERMINATED);
}

void ProxyResolverMojo::Job::Cancel() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback_.is_null());
  callback_.Reset();
}

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

void ProxyResolverMojo::Job::OnConnectionError() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << "ProxyResolverMojo::Job::OnConnectionError";
  resolver_->RemoveJob(this);
}

void ProxyResolverMojo::Job::ReportResult(
    int32_t error,
    mojo::Array<interfaces::ProxyServerPtr> proxy_servers) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << "ProxyResolverMojo::Job::ReportResult: " << error;

  if (error == OK) {
    *results_ = proxy_servers.To<ProxyInfo>();
    DVLOG(1) << "Servers: " << results_->ToPacString();
  }

  CompletionCallback callback = callback_;
  callback_.Reset();
  resolver_->RemoveJob(this);
  callback.Run(error);
}

ProxyResolverMojo::ProxyResolverMojo(
    interfaces::ProxyResolverPtr resolver_ptr,
    HostResolver* host_resolver,
    scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner,
    scoped_ptr<ProxyResolverErrorObserver> error_observer,
    NetLog* net_log)
    : mojo_proxy_resolver_ptr_(resolver_ptr.Pass()),
      host_resolver_(host_resolver),
      error_observer_(error_observer.Pass()),
      net_log_(net_log),
      on_delete_callback_runner_(on_delete_callback_runner.Pass()) {
  mojo_proxy_resolver_ptr_.set_connection_error_handler(base::Bind(
      &ProxyResolverMojo::OnConnectionError, base::Unretained(this)));
}

ProxyResolverMojo::~ProxyResolverMojo() {
  DCHECK(thread_checker_.CalledOnValidThread());
  // All pending requests should have been cancelled.
  DCHECK(pending_jobs_.empty());
}

void ProxyResolverMojo::OnConnectionError() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << "ProxyResolverMojo::OnConnectionError";

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

void ProxyResolverMojo::RemoveJob(Job* job) {
  DCHECK(thread_checker_.CalledOnValidThread());
  size_t num_erased = pending_jobs_.erase(job);
  DCHECK(num_erased);
  delete job;
}

int ProxyResolverMojo::GetProxyForURL(const GURL& url,
                                      ProxyInfo* results,
                                      const CompletionCallback& callback,
                                      RequestHandle* request,
                                      const BoundNetLog& net_log) {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (!mojo_proxy_resolver_ptr_)
    return ERR_PAC_SCRIPT_TERMINATED;

  Job* job = new Job(this, url, results, callback, net_log);
  bool inserted = pending_jobs_.insert(job).second;
  DCHECK(inserted);
  *request = job;

  return ERR_IO_PENDING;
}

void ProxyResolverMojo::CancelRequest(RequestHandle request) {
  DCHECK(thread_checker_.CalledOnValidThread());
  Job* job = static_cast<Job*>(request);
  DCHECK(job);
  job->Cancel();
  RemoveJob(job);
}

LoadState ProxyResolverMojo::GetLoadState(RequestHandle request) const {
  Job* job = static_cast<Job*>(request);
  CHECK_EQ(1u, pending_jobs_.count(job));
  return job->GetLoadState();
}

}  // 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 BoundNetLog.
class ProxyResolverFactoryMojo::Job
    : public ClientMixin<interfaces::ProxyResolverFactoryRequestClient>,
      public ProxyResolverFactory::Request {
 public:
  Job(ProxyResolverFactoryMojo* factory,
      const scoped_refptr<ProxyResolverScriptData>& pac_script,
      scoped_ptr<ProxyResolver>* resolver,
      const CompletionCallback& callback,
      scoped_ptr<ProxyResolverErrorObserver> error_observer)
      : ClientMixin<interfaces::ProxyResolverFactoryRequestClient>(
            factory->host_resolver_,
            error_observer.get(),
            factory->net_log_,
            BoundNetLog()),
        factory_(factory),
        resolver_(resolver),
        callback_(callback),
        binding_(this),
        error_observer_(error_observer.Pass()) {
    interfaces::ProxyResolverFactoryRequestClientPtr client_ptr;
    binding_.Bind(mojo::GetProxy(&client_ptr));
    on_delete_callback_runner_ = factory_->mojo_proxy_factory_->CreateResolver(
        mojo::String::From(pac_script->utf16()), mojo::GetProxy(&resolver_ptr_),
        client_ptr.Pass());
    resolver_ptr_.set_connection_error_handler(
        base::Bind(&ProxyResolverFactoryMojo::Job::OnConnectionError,
                   base::Unretained(this)));
    binding_.set_connection_error_handler(
        base::Bind(&ProxyResolverFactoryMojo::Job::OnConnectionError,
                   base::Unretained(this)));
  }

  void OnConnectionError() { ReportResult(ERR_PAC_SCRIPT_TERMINATED); }

 private:
  void ReportResult(int32_t error) override {
    resolver_ptr_.set_connection_error_handler(mojo::Closure());
    binding_.set_connection_error_handler(mojo::Closure());
    if (error == OK) {
      resolver_->reset(
          new ProxyResolverMojo(resolver_ptr_.Pass(), factory_->host_resolver_,
                                on_delete_callback_runner_.Pass(),
                                error_observer_.Pass(), factory_->net_log_));
    }
    on_delete_callback_runner_.reset();
    callback_.Run(error);
  }

  ProxyResolverFactoryMojo* const factory_;
  scoped_ptr<ProxyResolver>* resolver_;
  const CompletionCallback callback_;
  interfaces::ProxyResolverPtr resolver_ptr_;
  mojo::Binding<interfaces::ProxyResolverFactoryRequestClient> binding_;
  scoped_ptr<base::ScopedClosureRunner> on_delete_callback_runner_;
  scoped_ptr<ProxyResolverErrorObserver> error_observer_;
};

ProxyResolverFactoryMojo::ProxyResolverFactoryMojo(
    MojoProxyResolverFactory* mojo_proxy_factory,
    HostResolver* host_resolver,
    const base::Callback<scoped_ptr<ProxyResolverErrorObserver>()>&
        error_observer_factory,
    NetLog* net_log)
    : ProxyResolverFactory(true),
      mojo_proxy_factory_(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<ProxyResolverScriptData>& pac_script,
    scoped_ptr<ProxyResolver>* resolver,
    const CompletionCallback& callback,
    scoped_ptr<ProxyResolverFactory::Request>* request) {
  DCHECK(resolver);
  DCHECK(request);
  if (pac_script->type() != ProxyResolverScriptData::TYPE_SCRIPT_CONTENTS ||
      pac_script->utf16().empty()) {
    return ERR_PAC_SCRIPT_FAILED;
  }
  request->reset(new Job(this, pac_script, resolver, callback,
                         error_observer_factory_.is_null()
                             ? nullptr
                             : error_observer_factory_.Run()));
  return ERR_IO_PENDING;
}

}  // namespace net
