// Copyright (c) 2012 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 "chrome/browser/net/connection_tester.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/base/request_priority.h"
#include "net/cert/cert_verifier.h"
#include "net/dns/host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_script_fetcher_impl.h"
#include "net/proxy/proxy_service.h"
#include "net/proxy/proxy_service_v8.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_storage.h"

#if !defined(OS_ANDROID) && !defined(OS_IOS)
#include "chrome/browser/net/firefox_proxy_settings.h"
#endif

namespace {

// ExperimentURLRequestContext ------------------------------------------------

// An instance of ExperimentURLRequestContext is created for each experiment
// run by ConnectionTester. The class initializes network dependencies according
// to the specified "experiment".
class ExperimentURLRequestContext : public net::URLRequestContext {
 public:
  explicit ExperimentURLRequestContext(
      net::URLRequestContext* proxy_request_context) :
#if !defined(OS_IOS)
        proxy_request_context_(proxy_request_context),
#endif
        storage_(this),
        weak_factory_(this) {}

  virtual ~ExperimentURLRequestContext() {}

  // Creates a proxy config service for |experiment|. On success returns net::OK
  // and fills |config_service| with a new pointer. Otherwise returns a network
  // error code.
  int CreateProxyConfigService(
      ConnectionTester::ProxySettingsExperiment experiment,
      scoped_ptr<net::ProxyConfigService>* config_service,
      base::Callback<void(int)> callback) {
    switch (experiment) {
      case ConnectionTester::PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS:
        return CreateSystemProxyConfigService(config_service);
      case ConnectionTester::PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS:
        return CreateFirefoxProxyConfigService(config_service, callback);
      case ConnectionTester::PROXY_EXPERIMENT_USE_AUTO_DETECT:
        config_service->reset(new net::ProxyConfigServiceFixed(
            net::ProxyConfig::CreateAutoDetect()));
        return net::OK;
      case ConnectionTester::PROXY_EXPERIMENT_USE_DIRECT:
        config_service->reset(new net::ProxyConfigServiceFixed(
            net::ProxyConfig::CreateDirect()));
        return net::OK;
      default:
        NOTREACHED();
        return net::ERR_UNEXPECTED;
    }
  }

  int Init(const ConnectionTester::Experiment& experiment,
           scoped_ptr<net::ProxyConfigService>* proxy_config_service,
           net::NetLog* net_log) {
    int rv;

    // Create a custom HostResolver for this experiment.
    scoped_ptr<net::HostResolver> host_resolver_tmp;
    rv = CreateHostResolver(experiment.host_resolver_experiment,
                            &host_resolver_tmp);
    if (rv != net::OK)
      return rv;  // Failure.
    storage_.set_host_resolver(host_resolver_tmp.Pass());

    // Create a custom ProxyService for this this experiment.
    scoped_ptr<net::ProxyService> experiment_proxy_service;
    rv = CreateProxyService(experiment.proxy_settings_experiment,
                            proxy_config_service, &experiment_proxy_service);
    if (rv != net::OK)
      return rv;  // Failure.
    storage_.set_proxy_service(experiment_proxy_service.release());

    // The rest of the dependencies are standard, and don't depend on the
    // experiment being run.
    storage_.set_cert_verifier(net::CertVerifier::CreateDefault());
    storage_.set_transport_security_state(new net::TransportSecurityState);
    storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults);
    storage_.set_http_auth_handler_factory(
        net::HttpAuthHandlerFactory::CreateDefault(host_resolver()));
    storage_.set_http_server_properties(
        scoped_ptr<net::HttpServerProperties>(
            new net::HttpServerPropertiesImpl()));

    net::HttpNetworkSession::Params session_params;
    session_params.host_resolver = host_resolver();
    session_params.cert_verifier = cert_verifier();
    session_params.transport_security_state = transport_security_state();
    session_params.proxy_service = proxy_service();
    session_params.ssl_config_service = ssl_config_service();
    session_params.http_auth_handler_factory = http_auth_handler_factory();
    session_params.http_server_properties = http_server_properties();
    session_params.net_log = net_log;
    scoped_refptr<net::HttpNetworkSession> network_session(
        new net::HttpNetworkSession(session_params));
    storage_.set_http_transaction_factory(new net::HttpCache(
        network_session.get(), net::HttpCache::DefaultBackend::InMemory(0)));
    // In-memory cookie store.
    storage_.set_cookie_store(
        content::CreateCookieStore(content::CookieStoreConfig()));

    return net::OK;
  }

 private:
  // Creates a host resolver for |experiment|. On success returns net::OK and
  // fills |host_resolver| with a new pointer. Otherwise returns a network
  // error code.
  int CreateHostResolver(
      ConnectionTester::HostResolverExperiment experiment,
      scoped_ptr<net::HostResolver>* host_resolver) {
    // Create a vanilla HostResolver that disables caching.
    const size_t kMaxJobs = 50u;
    const size_t kMaxRetryAttempts = 4u;
    net::HostResolver::Options options;
    options.max_concurrent_resolves = kMaxJobs;
    options.max_retry_attempts = kMaxRetryAttempts;
    options.enable_caching = false;
    scoped_ptr<net::HostResolver> resolver(
        net::HostResolver::CreateSystemResolver(options, NULL /* NetLog */));

    // Modify it slightly based on the experiment being run.
    switch (experiment) {
      case ConnectionTester::HOST_RESOLVER_EXPERIMENT_PLAIN:
        break;
      case ConnectionTester::HOST_RESOLVER_EXPERIMENT_DISABLE_IPV6:
        resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
        break;
      case ConnectionTester::HOST_RESOLVER_EXPERIMENT_IPV6_PROBE: {
        // The system HostResolver will probe by default.
        break;
      }
      default:
        NOTREACHED();
        return net::ERR_UNEXPECTED;
    }
    host_resolver->swap(resolver);
    return net::OK;
  }

  // Creates a proxy service for |experiment|. On success returns net::OK
  // and fills |experiment_proxy_service| with a new pointer. Otherwise returns
  // a network error code.
  int CreateProxyService(
      ConnectionTester::ProxySettingsExperiment experiment,
      scoped_ptr<net::ProxyConfigService>* proxy_config_service,
      scoped_ptr<net::ProxyService>* experiment_proxy_service) {
    if (CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kSingleProcess)) {
      // We can't create a standard proxy resolver in single-process mode.
      // Rather than falling-back to some other implementation, fail.
      return net::ERR_NOT_IMPLEMENTED;
    }

    net::DhcpProxyScriptFetcherFactory dhcp_factory;
    if (CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kDisableDhcpWpad)) {
      dhcp_factory.set_enabled(false);
    }

#if defined(OS_IOS)
    experiment_proxy_service->reset(
        net::ProxyService::CreateUsingSystemProxyResolver(
            proxy_config_service->release(), 0u, NULL));
#else
    experiment_proxy_service->reset(
        net::CreateProxyServiceUsingV8ProxyResolver(
            proxy_config_service->release(),
            new net::ProxyScriptFetcherImpl(proxy_request_context_),
            dhcp_factory.Create(proxy_request_context_),
            host_resolver(),
            NULL,
            NULL));
#endif

    return net::OK;
  }

  // Creates a proxy config service that pulls from the system proxy settings.
  // On success returns net::OK and fills |config_service| with a new pointer.
  // Otherwise returns a network error code.
  int CreateSystemProxyConfigService(
      scoped_ptr<net::ProxyConfigService>* config_service) {
#if defined(OS_LINUX) || defined(OS_OPENBSD)
    // TODO(eroman): This is not supported on Linux yet, because of how
    // construction needs ot happen on the UI thread.
    return net::ERR_NOT_IMPLEMENTED;
#else
    config_service->reset(net::ProxyService::CreateSystemProxyConfigService(
        base::ThreadTaskRunnerHandle::Get().get(), NULL));
    return net::OK;
#endif
  }

#if !defined(OS_ANDROID) && !defined(OS_IOS)
  static int FirefoxProxySettingsTask(
      FirefoxProxySettings* firefox_settings) {
    if (!FirefoxProxySettings::GetSettings(firefox_settings))
      return net::ERR_FILE_NOT_FOUND;
    return net::OK;
  }

  void FirefoxProxySettingsReply(
      scoped_ptr<net::ProxyConfigService>* config_service,
      FirefoxProxySettings* firefox_settings,
      base::Callback<void(int)> callback,
      int rv) {
    if (rv == net::OK) {
      if (FirefoxProxySettings::SYSTEM == firefox_settings->config_type()) {
        rv = CreateSystemProxyConfigService(config_service);
      } else {
        net::ProxyConfig config;
        if (firefox_settings->ToProxyConfig(&config))
          config_service->reset(new net::ProxyConfigServiceFixed(config));
        else
          rv = net::ERR_FAILED;
      }
    }
    callback.Run(rv);
  }
#endif

  // Creates a fixed proxy config service that is initialized using Firefox's
  // current proxy settings. On success returns net::OK and fills
  // |config_service| with a new pointer. Otherwise returns a network error
  // code.
  int CreateFirefoxProxyConfigService(
      scoped_ptr<net::ProxyConfigService>* config_service,
      base::Callback<void(int)> callback) {
#if defined(OS_ANDROID) || defined(OS_IOS)
    // Chrome on Android and iOS do not support Firefox settings.
    return net::ERR_NOT_IMPLEMENTED;
#else
    // Fetch Firefox's proxy settings (can fail if Firefox is not installed).
    FirefoxProxySettings* ff_settings = new FirefoxProxySettings();
    base::Callback<int(void)> task = base::Bind(
        &FirefoxProxySettingsTask, ff_settings);
    base::Callback<void(int)> reply = base::Bind(
        &ExperimentURLRequestContext::FirefoxProxySettingsReply,
        weak_factory_.GetWeakPtr(), config_service,
        base::Owned(ff_settings), callback);
    if (!content::BrowserThread::PostTaskAndReplyWithResult<int>(
            content::BrowserThread::FILE, FROM_HERE, task, reply))
      return net::ERR_FAILED;
    return net::ERR_IO_PENDING;
#endif
  }

#if !defined(OS_IOS)
  net::URLRequestContext* const proxy_request_context_;
#endif
  net::URLRequestContextStorage storage_;
  base::WeakPtrFactory<ExperimentURLRequestContext> weak_factory_;
};

}  // namespace

// ConnectionTester::TestRunner ----------------------------------------------

// TestRunner is a helper class for running an individual experiment. It can
// be deleted any time after it is started, and this will abort the request.
class ConnectionTester::TestRunner : public net::URLRequest::Delegate {
 public:
  // |tester| must remain alive throughout the TestRunner's lifetime.
  // |tester| will be notified of completion.
  TestRunner(ConnectionTester* tester, net::NetLog* net_log)
      : tester_(tester),
        net_log_(net_log),
        weak_factory_(this) {}

  // Finish running |experiment| once a ProxyConfigService has been created.
  // In the case of a FirefoxProxyConfigService, this will be called back
  // after disk access has completed.
  void ProxyConfigServiceCreated(
    const Experiment& experiment,
    scoped_ptr<net::ProxyConfigService>* proxy_config_service, int status);

  // Starts running |experiment|. Notifies tester->OnExperimentCompleted() when
  // it is done.
  void Run(const Experiment& experiment);

  // Overridden from net::URLRequest::Delegate:
  virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
  virtual void OnReadCompleted(net::URLRequest* request,
                               int bytes_read) OVERRIDE;
  // TODO(eroman): handle cases requiring authentication.

 private:
  // The number of bytes to read each response body chunk.
  static const int kReadBufferSize = 1024;

  // Starts reading the response's body (and keeps reading until an error or
  // end of stream).
  void ReadBody(net::URLRequest* request);

  // Called when the request has completed (for both success and failure).
  void OnResponseCompleted(net::URLRequest* request);
  void OnExperimentCompletedWithResult(int result);

  ConnectionTester* tester_;
  scoped_ptr<ExperimentURLRequestContext> request_context_;
  scoped_ptr<net::URLRequest> request_;
  net::NetLog* net_log_;

  base::WeakPtrFactory<TestRunner> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(TestRunner);
};

void ConnectionTester::TestRunner::OnResponseStarted(net::URLRequest* request) {
  if (!request->status().is_success()) {
    OnResponseCompleted(request);
    return;
  }

  // Start reading the body.
  ReadBody(request);
}

void ConnectionTester::TestRunner::OnReadCompleted(net::URLRequest* request,
                                                   int bytes_read) {
  if (bytes_read <= 0) {
    OnResponseCompleted(request);
    return;
  }

  // Keep reading until the stream is closed. Throw the data read away.
  ReadBody(request);
}

void ConnectionTester::TestRunner::ReadBody(net::URLRequest* request) {
  // Read the response body |kReadBufferSize| bytes at a time.
  scoped_refptr<net::IOBuffer> unused_buffer(
      new net::IOBuffer(kReadBufferSize));
  int num_bytes;
  if (request->Read(unused_buffer.get(), kReadBufferSize, &num_bytes)) {
    OnReadCompleted(request, num_bytes);
  } else if (!request->status().is_io_pending()) {
    // Read failed synchronously.
    OnResponseCompleted(request);
  }
}

void ConnectionTester::TestRunner::OnResponseCompleted(
    net::URLRequest* request) {
  int result = net::OK;
  if (!request->status().is_success()) {
    DCHECK_NE(net::ERR_IO_PENDING, request->status().error());
    result = request->status().error();
  }

  // Post a task to notify the parent rather than handling it right away,
  // to avoid re-entrancy problems with URLRequest. (Don't want the caller
  // to end up deleting the URLRequest while in the middle of processing).
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&TestRunner::OnExperimentCompletedWithResult,
                 weak_factory_.GetWeakPtr(), result));
}

void ConnectionTester::TestRunner::OnExperimentCompletedWithResult(int result) {
  tester_->OnExperimentCompleted(result);
}

void ConnectionTester::TestRunner::ProxyConfigServiceCreated(
    const Experiment& experiment,
    scoped_ptr<net::ProxyConfigService>* proxy_config_service,
    int status) {
  if (status == net::OK)
    status = request_context_->Init(experiment,
                                    proxy_config_service,
                                    net_log_);
  if (status != net::OK) {
    tester_->OnExperimentCompleted(status);
    return;
  }
  // Fetch a request using the experimental context.
  request_ = request_context_->CreateRequest(
      experiment.url, net::DEFAULT_PRIORITY, this);
  request_->Start();
}

void ConnectionTester::TestRunner::Run(const Experiment& experiment) {
  // Try to create a net::URLRequestContext for this experiment.
  request_context_.reset(
      new ExperimentURLRequestContext(tester_->proxy_request_context_));
  scoped_ptr<net::ProxyConfigService>* proxy_config_service =
      new scoped_ptr<net::ProxyConfigService>();
  base::Callback<void(int)> config_service_callback =
      base::Bind(
          &TestRunner::ProxyConfigServiceCreated, weak_factory_.GetWeakPtr(),
          experiment, base::Owned(proxy_config_service));
  int rv = request_context_->CreateProxyConfigService(
      experiment.proxy_settings_experiment,
      proxy_config_service, config_service_callback);
  if (rv != net::ERR_IO_PENDING)
    ProxyConfigServiceCreated(experiment, proxy_config_service, rv);
}

// ConnectionTester ----------------------------------------------------------

ConnectionTester::ConnectionTester(
    Delegate* delegate,
    net::URLRequestContext* proxy_request_context,
    net::NetLog* net_log)
    : delegate_(delegate),
      proxy_request_context_(proxy_request_context),
      net_log_(net_log) {
  DCHECK(delegate);
  DCHECK(proxy_request_context);
}

ConnectionTester::~ConnectionTester() {
  // Cancellation happens automatically by deleting test_runner_.
}

void ConnectionTester::RunAllTests(const GURL& url) {
  // Select all possible experiments to run. (In no particular order).
  // It is possible that some of these experiments are actually duplicates.
  GetAllPossibleExperimentCombinations(url, &remaining_experiments_);

  delegate_->OnStartConnectionTestSuite();
  StartNextExperiment();
}

// static
base::string16 ConnectionTester::ProxySettingsExperimentDescription(
    ProxySettingsExperiment experiment) {
  // TODO(eroman): Use proper string resources.
  switch (experiment) {
    case PROXY_EXPERIMENT_USE_DIRECT:
      return base::ASCIIToUTF16("Don't use any proxy");
    case PROXY_EXPERIMENT_USE_SYSTEM_SETTINGS:
      return base::ASCIIToUTF16("Use system proxy settings");
    case PROXY_EXPERIMENT_USE_FIREFOX_SETTINGS:
      return base::ASCIIToUTF16("Use Firefox's proxy settings");
    case PROXY_EXPERIMENT_USE_AUTO_DETECT:
      return base::ASCIIToUTF16("Auto-detect proxy settings");
    default:
      NOTREACHED();
      return base::string16();
  }
}

// static
base::string16 ConnectionTester::HostResolverExperimentDescription(
    HostResolverExperiment experiment) {
  // TODO(eroman): Use proper string resources.
  switch (experiment) {
    case HOST_RESOLVER_EXPERIMENT_PLAIN:
      return base::string16();
    case HOST_RESOLVER_EXPERIMENT_DISABLE_IPV6:
      return base::ASCIIToUTF16("Disable IPv6 host resolving");
    case HOST_RESOLVER_EXPERIMENT_IPV6_PROBE:
      return base::ASCIIToUTF16("Probe for IPv6 host resolving");
    default:
      NOTREACHED();
      return base::string16();
  }
}

// static
void ConnectionTester::GetAllPossibleExperimentCombinations(
    const GURL& url,
    ConnectionTester::ExperimentList* list) {
  list->clear();
  for (size_t resolver_experiment = 0;
       resolver_experiment < HOST_RESOLVER_EXPERIMENT_COUNT;
       ++resolver_experiment) {
    for (size_t proxy_experiment = 0;
         proxy_experiment < PROXY_EXPERIMENT_COUNT;
         ++proxy_experiment) {
      Experiment experiment(
          url,
          static_cast<ProxySettingsExperiment>(proxy_experiment),
          static_cast<HostResolverExperiment>(resolver_experiment));
      list->push_back(experiment);
    }
  }
}

void ConnectionTester::StartNextExperiment() {
  DCHECK(!remaining_experiments_.empty());
  DCHECK(!current_test_runner_.get());

  delegate_->OnStartConnectionTestExperiment(current_experiment());

  current_test_runner_.reset(new TestRunner(this, net_log_));
  current_test_runner_->Run(current_experiment());
}

void ConnectionTester::OnExperimentCompleted(int result) {
  Experiment current = current_experiment();

  // Advance to the next experiment.
  remaining_experiments_.erase(remaining_experiments_.begin());
  current_test_runner_.reset();

  // Notify the delegate of completion.
  delegate_->OnCompletedConnectionTestExperiment(current, result);

  if (remaining_experiments_.empty()) {
    delegate_->OnCompletedConnectionTestSuite();
  } else {
    StartNextExperiment();
  }
}
