// Copyright 2016 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 "components/cronet/ios/cronet_environment.h"

#include <utility>

#include "base/atomicops.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/mac/foundation_util.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"
#include "components/cronet/cronet_buildflags.h"
#include "components/cronet/cronet_global_state.h"
#include "components/cronet/cronet_prefs_manager.h"
#include "components/cronet/histogram_manager.h"
#include "components/prefs/pref_filter.h"
#include "ios/net/cookies/cookie_store_ios.h"
#include "ios/net/cookies/cookie_store_ios_client.h"
#include "ios/web/public/global_state/ios_global_state.h"
#include "ios/web/public/global_state/ios_global_state_configuration.h"
#include "ios/web/public/user_agent.h"
#include "net/base/http_user_agent_settings.h"
#include "net/base/network_change_notifier.h"
#include "net/base/url_util.h"
#include "net/cert/cert_verifier.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/http_util.h"
#include "net/log/file_net_log_observer.h"
#include "net/log/net_log.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/net_log_util.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/ssl_client_socket.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/ssl_key_logger_impl.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.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_storage.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "url/scheme_host_port.h"
#include "url/url_util.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace {

// Request context getter for Cronet.
class CronetURLRequestContextGetter : public net::URLRequestContextGetter {
 public:
  CronetURLRequestContextGetter(
      cronet::CronetEnvironment* environment,
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
      : environment_(environment), task_runner_(task_runner) {}

  net::URLRequestContext* GetURLRequestContext() override {
    DCHECK(environment_);
    return environment_->GetURLRequestContext();
  }

  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
      const override {
    return task_runner_;
  }

 private:
  // Must be called on the IO thread.
  ~CronetURLRequestContextGetter() override {}

  cronet::CronetEnvironment* environment_;
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  DISALLOW_COPY_AND_ASSIGN(CronetURLRequestContextGetter);
};

// Cronet implementation of net::CookieStoreIOSClient.
// Used to provide Cronet Network IO TaskRunner.
class CronetCookieStoreIOSClient : public net::CookieStoreIOSClient {
 public:
  CronetCookieStoreIOSClient(
      const scoped_refptr<base::SequencedTaskRunner>& task_runner)
      : task_runner_(task_runner) {}

  scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override {
    return task_runner_;
  }

 private:
  ~CronetCookieStoreIOSClient() override {}

  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  DISALLOW_COPY_AND_ASSIGN(CronetCookieStoreIOSClient);
};

void SignalEvent(base::WaitableEvent* event) {
  event->Signal();
}

// TODO(eroman): Creating the file(s) for a netlog is an internal detail for
// FileNetLogObsever. This code assumes that the unbounded format is being used,
// which writes a single file at |path| (creating or overwriting it).
bool IsNetLogPathValid(const base::FilePath& path) {
  base::ScopedFILE file(base::OpenFile(path, "w"));
  return !!file;
}

}  // namespace

namespace cronet {

const double CronetEnvironment::kKeepDefaultThreadPriority = -1;

base::SingleThreadTaskRunner* CronetEnvironment::GetNetworkThreadTaskRunner()
    const {
  if (network_io_thread_) {
    return network_io_thread_->task_runner().get();
  }
  return ios_global_state::GetSharedNetworkIOThreadTaskRunner().get();
}

void CronetEnvironment::PostToNetworkThread(const base::Location& from_here,
                                            const base::Closure& task) {
  GetNetworkThreadTaskRunner()->PostTask(from_here, task);
}

net::URLRequestContext* CronetEnvironment::GetURLRequestContext() const {
  return main_context_.get();
}

net::URLRequestContextGetter* CronetEnvironment::GetURLRequestContextGetter()
    const {
  return main_context_getter_.get();
}

bool CronetEnvironment::StartNetLog(base::FilePath::StringType file_name,
                                    bool log_bytes) {
  if (file_name.empty())
    return false;

  base::FilePath path(file_name);
  if (!IsNetLogPathValid(path)) {
    LOG(ERROR) << "Can not start NetLog to " << path.value() << ": "
               << strerror(errno);
    return false;
  }

  LOG(WARNING) << "Starting NetLog to " << path.value();
  PostToNetworkThread(FROM_HERE,
                      base::Bind(&CronetEnvironment::StartNetLogOnNetworkThread,
                                 base::Unretained(this), path, log_bytes));

  return true;
}

void CronetEnvironment::StartNetLogOnNetworkThread(const base::FilePath& path,
                                                   bool log_bytes) {
  DCHECK(net_log_);

  if (file_net_log_observer_)
    return;

  net::NetLogCaptureMode capture_mode =
      log_bytes ? net::NetLogCaptureMode::IncludeSocketBytes()
                : net::NetLogCaptureMode::Default();

  file_net_log_observer_ =
      net::FileNetLogObserver::CreateUnbounded(path, nullptr);
  file_net_log_observer_->StartObserving(main_context_->net_log(),
                                         capture_mode);
  LOG(WARNING) << "Started NetLog";
}

void CronetEnvironment::StopNetLog() {
  base::WaitableEvent log_stopped_event(
      base::WaitableEvent::ResetPolicy::MANUAL,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  PostToNetworkThread(FROM_HERE,
                      base::Bind(&CronetEnvironment::StopNetLogOnNetworkThread,
                                 base::Unretained(this), &log_stopped_event));
  log_stopped_event.Wait();
}

void CronetEnvironment::StopNetLogOnNetworkThread(
    base::WaitableEvent* log_stopped_event) {
  if (file_net_log_observer_) {
    DLOG(WARNING) << "Stopped NetLog.";
    file_net_log_observer_->StopObserving(
        GetNetLogInfo(), base::BindOnce(&SignalEvent, log_stopped_event));
    file_net_log_observer_.reset();
  } else {
    log_stopped_event->Signal();
  }
}

std::unique_ptr<base::DictionaryValue> CronetEnvironment::GetNetLogInfo()
    const {
  std::unique_ptr<base::DictionaryValue> net_info =
      net::GetNetInfo(main_context_.get(), net::NET_INFO_ALL_SOURCES);
  if (effective_experimental_options_) {
    net_info->Set("cronetExperimentalParams",
                  effective_experimental_options_->CreateDeepCopy());
  }
  return net_info;
}

net::HttpNetworkSession* CronetEnvironment::GetHttpNetworkSession(
    net::URLRequestContext* context) {
  DCHECK(context);
  if (!context->http_transaction_factory())
    return nullptr;

  return context->http_transaction_factory()->GetSession();
}

void CronetEnvironment::AddQuicHint(const std::string& host,
                                    int port,
                                    int alternate_port) {
  DCHECK(port == alternate_port);
  quic_hints_.push_back(net::HostPortPair(host, port));
}

CronetEnvironment::CronetEnvironment(const std::string& user_agent,
                                     bool user_agent_partial)
    : http2_enabled_(false),
      quic_enabled_(false),
      brotli_enabled_(false),
      http_cache_(URLRequestContextConfig::HttpCacheType::DISK),
      user_agent_(user_agent),
      user_agent_partial_(user_agent_partial),
      net_log_(new net::NetLog),
      enable_pkp_bypass_for_local_trust_anchors_(true),
      network_thread_priority_(kKeepDefaultThreadPriority) {}

void CronetEnvironment::Start() {
  // Threads setup.
  file_thread_.reset(new base::Thread("Chrome File Thread"));
  file_thread_->StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  // Fetching the task_runner will create the shared thread if necessary.
  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
      ios_global_state::GetSharedNetworkIOThreadTaskRunner();
  if (!task_runner) {
    network_io_thread_.reset(
        new CronetNetworkThread("Chrome Network IO Thread", this));
    network_io_thread_->StartWithOptions(
        base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
  }

  net::SetCookieStoreIOSClient(new CronetCookieStoreIOSClient(
      CronetEnvironment::GetNetworkThreadTaskRunner()));

  main_context_getter_ = new CronetURLRequestContextGetter(
      this, CronetEnvironment::GetNetworkThreadTaskRunner());
  base::subtle::MemoryBarrier();
  PostToNetworkThread(FROM_HERE,
                      base::Bind(&CronetEnvironment::InitializeOnNetworkThread,
                                 base::Unretained(this)));
}

void CronetEnvironment::CleanUpOnNetworkThread() {
  // TODO(lilyhoughton) make unregistering of this work.
  // net::HTTPProtocolHandlerDelegate::SetInstance(nullptr);

  // TODO(lilyhoughton) this can only be run once, so right now leaking it.
  // Should be be called when the _last_ CronetEnvironment is destroyed.
  // base::TaskScheduler* ts = base::TaskScheduler::GetInstance();
  // if (ts)
  //  ts->Shutdown();

  if (cronet_prefs_manager_) {
    cronet_prefs_manager_->PrepareForShutdown();
  }

  // TODO(lilyhoughton) this should be smarter about making sure there are no
  // pending requests, etc.
  main_context_.reset();

  // cronet_prefs_manager_ should be deleted on the network thread.
  cronet_prefs_manager_.reset();
}

CronetEnvironment::~CronetEnvironment() {
  // Deleting a thread blocks the current thread and waits until all pending
  // tasks are completed.
  network_io_thread_.reset();
  file_thread_.reset();
}

void CronetEnvironment::InitializeOnNetworkThread() {
  DCHECK(GetNetworkThreadTaskRunner()->BelongsToCurrentThread());
  base::DisallowBlocking();

  static bool ssl_key_log_file_set = false;
  if (!ssl_key_log_file_set && !ssl_key_log_file_name_.empty()) {
    ssl_key_log_file_set = true;
    base::FilePath ssl_key_log_file(ssl_key_log_file_name_);
    net::SSLClientSocket::SetSSLKeyLogger(
        std::make_unique<net::SSLKeyLoggerImpl>(ssl_key_log_file));
  }

  if (user_agent_partial_)
    user_agent_ = web::BuildUserAgentFromProduct(user_agent_);

  // Cache
  base::FilePath storage_path;
  if (!base::PathService::Get(base::DIR_CACHE, &storage_path))
    return;
  storage_path = storage_path.Append(FILE_PATH_LITERAL("cronet"));

  URLRequestContextConfigBuilder context_config_builder;
  context_config_builder.enable_quic = quic_enabled_;   // Enable QUIC.
  context_config_builder.quic_user_agent_id =
      getDefaultQuicUserAgentId();                      // QUIC User Agent ID.
  context_config_builder.enable_spdy = http2_enabled_;  // Enable HTTP/2.
  context_config_builder.http_cache = http_cache_;      // Set HTTP cache.
  context_config_builder.storage_path =
      storage_path.value();  // Storage path for http cache and prefs storage.
  context_config_builder.accept_language =
      accept_language_;  // Accept-Language request header field.
  context_config_builder.user_agent =
      user_agent_;  // User-Agent request header field.
  context_config_builder.experimental_options =
      experimental_options_;  // Set experimental Cronet options.
  context_config_builder.mock_cert_verifier = std::move(
      mock_cert_verifier_);  // MockCertVerifier to use for testing purposes.
  if (network_thread_priority_ != kKeepDefaultThreadPriority)
    context_config_builder.network_thread_priority = network_thread_priority_;
  std::unique_ptr<URLRequestContextConfig> config =
      context_config_builder.Build();

  config->pkp_list = std::move(pkp_list_);

  net::URLRequestContextBuilder context_builder;

  // Explicitly disable the persister for Cronet to avoid persistence of dynamic
  // HPKP.  This is a safety measure ensuring that nobody enables the
  // persistence of HPKP by specifying transport_security_persister_path in the
  // future.
  context_builder.set_transport_security_persister_path(base::FilePath());

  config->ConfigureURLRequestContextBuilder(&context_builder, net_log_.get());

  effective_experimental_options_ =
      std::move(config->effective_experimental_options);

  std::unique_ptr<net::MappedHostResolver> mapped_host_resolver(
      new net::MappedHostResolver(
          net::HostResolver::CreateDefaultResolver(nullptr)));

  if (!config->storage_path.empty()) {
    cronet_prefs_manager_ = std::make_unique<CronetPrefsManager>(
        config->storage_path, GetNetworkThreadTaskRunner(),
        file_thread_->task_runner(), false /* nqe */, false /* host_cache */,
        net_log_.get(), &context_builder);
  }

  context_builder.set_host_resolver(std::move(mapped_host_resolver));

  // TODO(690969): This behavior matches previous behavior of CookieStoreIOS in
  // CrNet, but should change to adhere to App's Cookie Accept Policy instead
  // of changing it.
  [[NSHTTPCookieStorage sharedHTTPCookieStorage]
      setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
  auto cookie_store = std::make_unique<net::CookieStoreIOS>(
      [NSHTTPCookieStorage sharedHTTPCookieStorage], nullptr /* net_log */);
  context_builder.SetCookieStore(std::move(cookie_store));

  context_builder.set_enable_brotli(brotli_enabled_);
  main_context_ = context_builder.Build();

  for (const auto& quic_hint : quic_hints_) {
    url::CanonHostInfo host_info;
    std::string canon_host(net::CanonicalizeHost(quic_hint.host(), &host_info));
    if (!host_info.IsIPAddress() &&
        !net::IsCanonicalizedHostCompliant(canon_host)) {
      LOG(ERROR) << "Invalid QUIC hint host: " << quic_hint.host();
      continue;
    }

    net::AlternativeService alternative_service(net::kProtoQUIC, "",
                                                quic_hint.port());

    url::SchemeHostPort quic_hint_server("https", quic_hint.host(),
                                         quic_hint.port());
    main_context_->http_server_properties()->SetQuicAlternativeService(
        quic_hint_server, alternative_service, base::Time::Max(),
        quic::QuicTransportVersionVector());
  }

  main_context_->transport_security_state()
      ->SetEnablePublicKeyPinningBypassForLocalTrustAnchors(
          enable_pkp_bypass_for_local_trust_anchors_);

  // Iterate trhough PKP configuration for every host.
  for (const auto& pkp : config->pkp_list) {
    // Add the host pinning.
    main_context_->transport_security_state()->AddHPKP(
        pkp->host, pkp->expiration_date, pkp->include_subdomains,
        pkp->pin_hashes, GURL::EmptyGURL());
  }
}

void CronetEnvironment::SetNetworkThreadPriority(double priority) {
  DCHECK_LE(priority, 1.0);
  DCHECK_GE(priority, 0.0);
  network_thread_priority_ = priority;
  if (network_io_thread_) {
    PostToNetworkThread(
        FROM_HERE,
        base::BindRepeating(
            &CronetEnvironment::SetNetworkThreadPriorityOnNetworkThread,
            base::Unretained(this), priority));
  }
}

std::string CronetEnvironment::user_agent() {
  const net::HttpUserAgentSettings* user_agent_settings =
      main_context_->http_user_agent_settings();
  if (!user_agent_settings) {
    return nullptr;
  }

  return user_agent_settings->GetUserAgent();
}

std::vector<uint8_t> CronetEnvironment::GetHistogramDeltas() {
  std::vector<uint8_t> data;
#if BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
  NOTREACHED() << "Histogram support is disabled";
#else   // BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
  if (!HistogramManager::GetInstance()->GetDeltas(&data))
    return std::vector<uint8_t>();
#endif  // BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
  return data;
}

void CronetEnvironment::SetHostResolverRules(const std::string& rules) {
  base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED);
  PostToNetworkThread(
      FROM_HERE,
      base::Bind(&CronetEnvironment::SetHostResolverRulesOnNetworkThread,
                 base::Unretained(this), rules, &event));
  event.Wait();
}

void CronetEnvironment::SetHostResolverRulesOnNetworkThread(
    const std::string& rules,
    base::WaitableEvent* event) {
  static_cast<net::MappedHostResolver*>(main_context_->host_resolver())
      ->SetRulesFromString(rules);
  event->Signal();
}

void CronetEnvironment::SetNetworkThreadPriorityOnNetworkThread(
    double priority) {
  DCHECK(GetNetworkThreadTaskRunner()->BelongsToCurrentThread());
  cronet::SetNetworkThreadPriorityOnNetworkThread(priority);
}

std::string CronetEnvironment::getDefaultQuicUserAgentId() const {
  return base::SysNSStringToUTF8([[NSBundle mainBundle]
             objectForInfoDictionaryKey:@"CFBundleDisplayName"]) +
         " Cronet/" + CRONET_VERSION;
}

base::SingleThreadTaskRunner* CronetEnvironment::GetFileThreadRunnerForTesting()
    const {
  return file_thread_->task_runner().get();
}

base::SingleThreadTaskRunner*
CronetEnvironment::GetNetworkThreadRunnerForTesting() const {
  return GetNetworkThreadTaskRunner();
}

CronetEnvironment::CronetNetworkThread::CronetNetworkThread(
    const std::string& name,
    cronet::CronetEnvironment* cronet_environment)
    : base::Thread(name), cronet_environment_(cronet_environment) {}

CronetEnvironment::CronetNetworkThread::~CronetNetworkThread() {
  Stop();
}

void CronetEnvironment::CronetNetworkThread::CleanUp() {
  cronet_environment_->CleanUpOnNetworkThread();
}

}  // namespace cronet
