// Copyright 2014 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 "chromecast/browser/url_request_context_factory.h"

#include <utility>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "chromecast/base/cast_features.h"
#include "chromecast/base/chromecast_switches.h"
#include "chromecast/browser/cast_browser_process.h"
#include "chromecast/browser/cast_http_user_agent_settings.h"
#include "chromecast/browser/cast_network_delegate.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "content/public/common/url_constants.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_policy_status.h"
#include "net/cert/do_nothing_ct_verifier.h"
#include "net/cert_net/nss_ocsp.h"
#include "net/cookies/cookie_store.h"
#include "net/dns/host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_stream_factory.h"
#include "net/proxy/proxy_service.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"

namespace chromecast {
namespace shell {

namespace {

const char kCookieStoreFile[] = "Cookies";

// A CTPolicyEnforcer that accepts all certificates.
class IgnoresCTPolicyEnforcer : public net::CTPolicyEnforcer {
 public:
  IgnoresCTPolicyEnforcer() = default;
  ~IgnoresCTPolicyEnforcer() override = default;

  net::ct::CTPolicyCompliance CheckCompliance(
      net::X509Certificate* cert,
      const net::SCTList& verified_scts,
      const net::NetLogWithSource& net_log) override {
    return net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;
  }
};

bool IgnoreCertificateErrors() {
  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  return cmd_line->HasSwitch(switches::kIgnoreCertificateErrors);
}

}  // namespace

// Private classes to expose URLRequestContextGetter that call back to the
// URLRequestContextFactory to create the URLRequestContext on demand.
//
// The URLRequestContextFactory::URLRequestContextGetter class is used for both
// the system and media URLRequestCotnexts.
class URLRequestContextFactory::URLRequestContextGetter
    : public net::URLRequestContextGetter {
 public:
  URLRequestContextGetter(URLRequestContextFactory* factory, bool is_media)
      : is_media_(is_media),
        factory_(factory) {
  }

  net::URLRequestContext* GetURLRequestContext() override {
    if (!request_context_) {
      if (is_media_) {
        request_context_.reset(factory_->CreateMediaRequestContext());
      } else {
        request_context_.reset(factory_->CreateSystemRequestContext());
#if defined(USE_NSS_CERTS)
        // Set request context used by NSS for Crl requests.
        net::SetURLRequestContextForNSSHttpIO(request_context_.get());
#endif  // defined(USE_NSS_CERTS)
      }
    }
    return request_context_.get();
  }

  scoped_refptr<base::SingleThreadTaskRunner>
      GetNetworkTaskRunner() const override {
    return content::BrowserThread::GetTaskRunnerForThread(
        content::BrowserThread::IO);
  }

 private:
  ~URLRequestContextGetter() override {}

  const bool is_media_;
  URLRequestContextFactory* const factory_;
  std::unique_ptr<net::URLRequestContext> request_context_;

  DISALLOW_COPY_AND_ASSIGN(URLRequestContextGetter);
};

// The URLRequestContextFactory::MainURLRequestContextGetter class is used for
// the main URLRequestContext.
class URLRequestContextFactory::MainURLRequestContextGetter
    : public net::URLRequestContextGetter {
 public:
  MainURLRequestContextGetter(
      URLRequestContextFactory* factory,
      content::BrowserContext* browser_context,
      content::ProtocolHandlerMap* protocol_handlers,
      content::URLRequestInterceptorScopedVector request_interceptors)
      : factory_(factory),
        cookie_path_(browser_context->GetPath().Append(kCookieStoreFile)),
        request_interceptors_(std::move(request_interceptors)) {
    std::swap(protocol_handlers_, *protocol_handlers);
  }

  net::URLRequestContext* GetURLRequestContext() override {
    if (!request_context_) {
      request_context_.reset(factory_->CreateMainRequestContext(
          cookie_path_, &protocol_handlers_, std::move(request_interceptors_)));
      protocol_handlers_.clear();
    }
    return request_context_.get();
  }

  scoped_refptr<base::SingleThreadTaskRunner>
      GetNetworkTaskRunner() const override {
    return content::BrowserThread::GetTaskRunnerForThread(
        content::BrowserThread::IO);
  }

 private:
  ~MainURLRequestContextGetter() override {}

  URLRequestContextFactory* const factory_;
  base::FilePath cookie_path_;
  content::ProtocolHandlerMap protocol_handlers_;
  content::URLRequestInterceptorScopedVector request_interceptors_;
  std::unique_ptr<net::URLRequestContext> request_context_;

  DISALLOW_COPY_AND_ASSIGN(MainURLRequestContextGetter);
};

URLRequestContextFactory::URLRequestContextFactory()
    : app_network_delegate_(CastNetworkDelegate::Create()),
      system_network_delegate_(CastNetworkDelegate::Create()),
      system_dependencies_initialized_(false),
      main_dependencies_initialized_(false),
      media_dependencies_initialized_(false) {}

URLRequestContextFactory::~URLRequestContextFactory() {
  pref_proxy_config_tracker_impl_->DetachFromPrefService();
}

void URLRequestContextFactory::InitializeOnUIThread(net::NetLog* net_log) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  // Cast http user agent settings must be initialized in UI thread
  // because it registers itself to pref notification observer which is not
  // thread safe.
  http_user_agent_settings_.reset(new CastHttpUserAgentSettings());

  // Proxy config service should be initialized in UI thread, since
  // ProxyConfigServiceDelegate on Android expects UI thread.
  pref_proxy_config_tracker_impl_ =
      base::WrapUnique<PrefProxyConfigTrackerImpl>(
          new PrefProxyConfigTrackerImpl(
              CastBrowserProcess::GetInstance()->pref_service(),
              content::BrowserThread::GetTaskRunnerForThread(
                  content::BrowserThread::IO)));

  proxy_config_service_ =
      pref_proxy_config_tracker_impl_->CreateTrackingProxyConfigService(
          nullptr);
  DCHECK(proxy_config_service_.get());
  net_log_ = net_log;
}

net::URLRequestContextGetter* URLRequestContextFactory::CreateMainGetter(
    content::BrowserContext* browser_context,
    content::ProtocolHandlerMap* protocol_handlers,
    content::URLRequestInterceptorScopedVector request_interceptors) {
  DCHECK(!main_getter_.get())
      << "Main URLRequestContextGetter already initialized";
  main_getter_ =
      new MainURLRequestContextGetter(this, browser_context, protocol_handlers,
                                      std::move(request_interceptors));
  return main_getter_.get();
}

net::URLRequestContextGetter* URLRequestContextFactory::GetMainGetter() {
  CHECK(main_getter_.get());
  return main_getter_.get();
}

net::URLRequestContextGetter* URLRequestContextFactory::GetSystemGetter() {
  if (!system_getter_.get()) {
    system_getter_ = new URLRequestContextGetter(this, false);
  }
  return system_getter_.get();
}

net::URLRequestContextGetter* URLRequestContextFactory::GetMediaGetter() {
  if (!media_getter_.get()) {
    media_getter_ = new URLRequestContextGetter(this, true);
  }
  return media_getter_.get();
}

void URLRequestContextFactory::InitializeSystemContextDependencies() {
  if (system_dependencies_initialized_)
    return;

  host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
  cert_verifier_ = net::CertVerifier::CreateDefault();
  ssl_config_service_ = new net::SSLConfigServiceDefaults;
  transport_security_state_.reset(new net::TransportSecurityState());
  // Certificate transparency is current disabled for Chromecast.
  cert_transparency_verifier_.reset(new net::DoNothingCTVerifier());
  ct_policy_enforcer_.reset(new IgnoresCTPolicyEnforcer());

  http_auth_handler_factory_ =
      net::HttpAuthHandlerFactory::CreateDefault(host_resolver_.get());

  // Use in-memory HttpServerProperties. Disk-based can improve performance
  // but benefit seems small (only helps 1st request to a server).
  http_server_properties_.reset(new net::HttpServerPropertiesImpl);

  DCHECK(proxy_config_service_);
  proxy_service_ = net::ProxyService::CreateUsingSystemProxyResolver(
      std::move(proxy_config_service_), NULL);
  system_dependencies_initialized_ = true;
}

void URLRequestContextFactory::InitializeMainContextDependencies(
    content::ProtocolHandlerMap* protocol_handlers,
    content::URLRequestInterceptorScopedVector request_interceptors) {
  if (main_dependencies_initialized_)
    return;

  std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory(
      new net::URLRequestJobFactoryImpl());
  // Keep ProtocolHandlers added in sync with
  // CastContentBrowserClient::IsHandledURL().
  bool set_protocol = false;
  for (content::ProtocolHandlerMap::iterator it = protocol_handlers->begin();
       it != protocol_handlers->end();
       ++it) {
    set_protocol = job_factory->SetProtocolHandler(
        it->first, base::WrapUnique(it->second.release()));
    DCHECK(set_protocol);
  }
  set_protocol = job_factory->SetProtocolHandler(
      url::kDataScheme, base::WrapUnique(new net::DataProtocolHandler));
  DCHECK(set_protocol);

  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableLocalFileAccesses)) {
    set_protocol = job_factory->SetProtocolHandler(
        url::kFileScheme,
        std::make_unique<net::FileProtocolHandler>(
            base::CreateTaskRunnerWithTraits(
                {base::MayBlock(), base::TaskPriority::BACKGROUND,
                 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
    DCHECK(set_protocol);
  }

  // Set up interceptors in the reverse order.
  std::unique_ptr<net::URLRequestJobFactory> top_job_factory =
      std::move(job_factory);
  for (auto i = request_interceptors.rbegin(); i != request_interceptors.rend();
       ++i) {
    top_job_factory.reset(new net::URLRequestInterceptingJobFactory(
        std::move(top_job_factory), std::move(*i)));
  }
  request_interceptors.clear();

  main_job_factory_ = std::move(top_job_factory);

  main_dependencies_initialized_ = true;
}

void URLRequestContextFactory::InitializeMediaContextDependencies(
    net::HttpTransactionFactory* transaction_factory) {
  if (media_dependencies_initialized_)
    return;

  media_transaction_factory_.reset(transaction_factory);
  media_dependencies_initialized_ = true;
}

void URLRequestContextFactory::PopulateNetworkSessionParams(
    bool ignore_certificate_errors,
    net::HttpNetworkSession::Params* session_params) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  session_params->ignore_certificate_errors = ignore_certificate_errors;

  // Enable QUIC if instructed by DCS. This remains constant for the lifetime of
  // the process.
  session_params->enable_quic = base::FeatureList::IsEnabled(kEnableQuic);
  LOG(INFO) << "Set HttpNetworkSessionParams.enable_quic = "
            << session_params->enable_quic;

  // Do not close idle sockets on memory pressure, otherwise it will open too
  // much connections to the server.
  session_params->disable_idle_sockets_close_on_memory_pressure = true;
}

net::URLRequestContext* URLRequestContextFactory::CreateSystemRequestContext() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  InitializeSystemContextDependencies();
  net::HttpNetworkSession::Params session_params;
  PopulateNetworkSessionParams(IgnoreCertificateErrors(), &session_params);
  system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
  system_cookie_store_ =
      content::CreateCookieStore(content::CookieStoreConfig());

  net::URLRequestContext* system_context = new net::URLRequestContext();
  system_context->set_host_resolver(host_resolver_.get());
  system_context->set_channel_id_service(channel_id_service_.get());
  system_context->set_cert_verifier(cert_verifier_.get());
  system_context->set_cert_transparency_verifier(
      cert_transparency_verifier_.get());
  system_context->set_ct_policy_enforcer(ct_policy_enforcer_.get());
  system_context->set_proxy_service(proxy_service_.get());
  system_context->set_ssl_config_service(ssl_config_service_.get());
  system_context->set_transport_security_state(
      transport_security_state_.get());
  system_context->set_http_auth_handler_factory(
      http_auth_handler_factory_.get());
  system_context->set_http_server_properties(http_server_properties_.get());
  system_context->set_http_user_agent_settings(
      http_user_agent_settings_.get());
  system_context->set_job_factory(system_job_factory_.get());
  system_context->set_cookie_store(system_cookie_store_.get());
  system_context->set_network_delegate(system_network_delegate_.get());
  system_context->set_net_log(net_log_);

  net::HttpNetworkSession::Context session_context;
  net::URLRequestContextBuilder::SetHttpNetworkSessionComponents(
      system_context, &session_context);
  system_transaction_factory_.reset(new net::HttpNetworkLayer(
      new net::HttpNetworkSession(session_params, session_context)));
  system_context->set_http_transaction_factory(
      system_transaction_factory_.get());

  return system_context;
}

net::URLRequestContext* URLRequestContextFactory::CreateMediaRequestContext() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  DCHECK(main_getter_.get())
      << "Getting MediaRequestContext before MainRequestContext";
  net::URLRequestContext* main_context = main_getter_->GetURLRequestContext();

  // Set non caching backend.
  net::HttpNetworkSession* main_session =
      main_transaction_factory_->GetSession();
  InitializeMediaContextDependencies(
      new net::HttpNetworkLayer(main_session));

  net::URLRequestContext* media_context = new net::URLRequestContext();
  media_context->CopyFrom(main_context);
  media_context->set_http_transaction_factory(
      media_transaction_factory_.get());
  media_context->set_net_log(net_log_);
  return media_context;
}

net::URLRequestContext* URLRequestContextFactory::CreateMainRequestContext(
    const base::FilePath& cookie_path,
    content::ProtocolHandlerMap* protocol_handlers,
    content::URLRequestInterceptorScopedVector request_interceptors) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  InitializeSystemContextDependencies();

  net::HttpNetworkSession::Params session_params;
  PopulateNetworkSessionParams(IgnoreCertificateErrors(), &session_params);
  InitializeMainContextDependencies(
      protocol_handlers, std::move(request_interceptors));

  content::CookieStoreConfig cookie_config(cookie_path, false, true, nullptr);
  main_cookie_store_ = content::CreateCookieStore(cookie_config);

  net::URLRequestContext* main_context = new net::URLRequestContext();
  main_context->set_host_resolver(host_resolver_.get());
  main_context->set_channel_id_service(channel_id_service_.get());
  main_context->set_cert_verifier(cert_verifier_.get());
  main_context->set_cert_transparency_verifier(
      cert_transparency_verifier_.get());
  main_context->set_ct_policy_enforcer(ct_policy_enforcer_.get());
  main_context->set_proxy_service(proxy_service_.get());
  main_context->set_ssl_config_service(ssl_config_service_.get());
  main_context->set_transport_security_state(transport_security_state_.get());
  main_context->set_http_auth_handler_factory(
      http_auth_handler_factory_.get());
  main_context->set_http_server_properties(http_server_properties_.get());
  main_context->set_cookie_store(main_cookie_store_.get());
  main_context->set_http_user_agent_settings(
      http_user_agent_settings_.get());

  main_context->set_http_transaction_factory(
      main_transaction_factory_.get());
  main_context->set_job_factory(main_job_factory_.get());
  main_context->set_network_delegate(app_network_delegate_.get());
  main_context->set_net_log(net_log_);

  net::HttpNetworkSession::Context session_context;
  net::URLRequestContextBuilder::SetHttpNetworkSessionComponents(
      main_context, &session_context);
  main_transaction_factory_.reset(new net::HttpNetworkLayer(
      new net::HttpNetworkSession(session_params, session_context)));
  main_context->set_http_transaction_factory(main_transaction_factory_.get());

  return main_context;
}

void URLRequestContextFactory::InitializeNetworkDelegates() {
  app_network_delegate_->Initialize();
  LOG(INFO) << "Initialized app network delegate.";
  system_network_delegate_->Initialize();
  LOG(INFO) << "Initialized system network delegate.";
}

}  // namespace shell
}  // namespace chromecast
