// Copyright 2017 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/cronet_prefs_manager.h"

#include <memory>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/cronet/host_cache_persistence_manager.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "net/http/http_server_properties_manager.h"
#include "net/nqe/network_qualities_prefs_manager.h"
#include "net/url_request/url_request_context_builder.h"

namespace cronet {
namespace {

// Name of the pref used for HTTP server properties persistence.
const char kHttpServerPropertiesPref[] = "net.http_server_properties";
// Name of preference directory.
const base::FilePath::CharType kPrefsDirectoryName[] =
    FILE_PATH_LITERAL("prefs");
// Name of preference file.
const base::FilePath::CharType kPrefsFileName[] =
    FILE_PATH_LITERAL("local_prefs.json");
// Current version of disk storage.
const int32_t kStorageVersion = 1;
// Version number used when the version of disk storage is unknown.
const uint32_t kStorageVersionUnknown = 0;
// Name of the pref used for host cache persistence.
const char kHostCachePref[] = "net.host_cache";
// Name of the pref used for NQE persistence.
const char kNetworkQualitiesPref[] = "net.network_qualities";

bool IsCurrentVersion(const base::FilePath& version_filepath) {
  if (!base::PathExists(version_filepath))
    return false;
  base::File version_file(version_filepath,
                          base::File::FLAG_OPEN | base::File::FLAG_READ);
  uint32_t version = kStorageVersionUnknown;
  int bytes_read =
      version_file.Read(0, reinterpret_cast<char*>(&version), sizeof(version));
  if (bytes_read != sizeof(version)) {
    DLOG(WARNING) << "Cannot read from version file.";
    return false;
  }
  return version == kStorageVersion;
}

// TODO(xunjieli): Handle failures.
void InitializeStorageDirectory(const base::FilePath& dir) {
  // Checks version file and clear old storage.
  base::FilePath version_filepath(dir.AppendASCII("version"));
  if (IsCurrentVersion(version_filepath)) {
    // The version is up to date, so there is nothing to do.
    return;
  }
  // Delete old directory recursively and create a new directory.
  // base::DeleteFile returns true if the directory does not exist, so it is
  // fine if there is nothing on disk.
  if (!(base::DeleteFile(dir, true) && base::CreateDirectory(dir))) {
    DLOG(WARNING) << "Cannot purge directory.";
    return;
  }
  base::File new_version_file(version_filepath, base::File::FLAG_CREATE_ALWAYS |
                                                    base::File::FLAG_WRITE);

  if (!new_version_file.IsValid()) {
    DLOG(WARNING) << "Cannot create a version file.";
    return;
  }

  DCHECK(new_version_file.created());
  uint32_t new_version = kStorageVersion;
  int bytes_written = new_version_file.Write(
      0, reinterpret_cast<char*>(&new_version), sizeof(new_version));
  if (bytes_written != sizeof(new_version)) {
    DLOG(WARNING) << "Cannot write to version file.";
    return;
  }
  base::FilePath prefs_dir = dir.Append(kPrefsDirectoryName);
  if (!base::CreateDirectory(prefs_dir)) {
    DLOG(WARNING) << "Cannot create prefs directory";
    return;
  }
}

// Connects the HttpServerPropertiesManager's storage to the prefs.
class PrefServiceAdapter
    : public net::HttpServerPropertiesManager::PrefDelegate {
 public:
  explicit PrefServiceAdapter(PrefService* pref_service)
      : pref_service_(pref_service), path_(kHttpServerPropertiesPref) {
    pref_change_registrar_.Init(pref_service_);
  }

  ~PrefServiceAdapter() override {}

  // PrefDelegate implementation.
  const base::DictionaryValue* GetServerProperties() const override {
    return pref_service_->GetDictionary(path_);
  }

  void SetServerProperties(const base::DictionaryValue& value,
                           base::OnceClosure callback) override {
    pref_service_->Set(path_, value);
    if (callback)
      pref_service_->CommitPendingWrite(std::move(callback));
  }

  void StartListeningForUpdates(
      const base::RepeatingClosure& callback) override {
    pref_change_registrar_.Add(path_, callback);
    // Notify the pref manager that settings are already loaded, as a result
    // of initializing the pref store synchornously.
    base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
  }

 private:
  PrefService* pref_service_;
  const std::string path_;
  PrefChangeRegistrar pref_change_registrar_;

  DISALLOW_COPY_AND_ASSIGN(PrefServiceAdapter);
};  // class PrefServiceAdapter

class NetworkQualitiesPrefDelegateImpl
    : public net::NetworkQualitiesPrefsManager::PrefDelegate {
 public:
  // Caller must guarantee that |pref_service| outlives |this|.
  explicit NetworkQualitiesPrefDelegateImpl(PrefService* pref_service)
      : pref_service_(pref_service),
        lossy_prefs_writing_task_posted_(false),
        weak_ptr_factory_(this) {
    DCHECK(pref_service_);
  }

  ~NetworkQualitiesPrefDelegateImpl() override {}

  // net::NetworkQualitiesPrefsManager::PrefDelegate implementation.
  void SetDictionaryValue(const base::DictionaryValue& value) override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    pref_service_->Set(kNetworkQualitiesPref, value);
    if (lossy_prefs_writing_task_posted_)
      return;

    // Post the task that schedules the writing of the lossy prefs.
    lossy_prefs_writing_task_posted_ = true;

    // Delay after which the task that schedules the writing of the lossy prefs.
    // This is needed in case the writing of the lossy prefs is not scheduled
    // automatically. The delay was chosen so that it is large enough that it
    // does not affect the startup performance.
    static const int32_t kUpdatePrefsDelaySeconds = 10;

    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(
            &NetworkQualitiesPrefDelegateImpl::SchedulePendingLossyWrites,
            weak_ptr_factory_.GetWeakPtr()),
        base::TimeDelta::FromSeconds(kUpdatePrefsDelaySeconds));
  }
  std::unique_ptr<base::DictionaryValue> GetDictionaryValue() override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    UMA_HISTOGRAM_EXACT_LINEAR("NQE.Prefs.ReadCount", 1, 2);
    return pref_service_->GetDictionary(kNetworkQualitiesPref)
        ->CreateDeepCopy();
  }

 private:
  // Schedules the writing of the lossy prefs.
  void SchedulePendingLossyWrites() {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    UMA_HISTOGRAM_EXACT_LINEAR("NQE.Prefs.WriteCount", 1, 2);
    pref_service_->SchedulePendingLossyWrites();
    lossy_prefs_writing_task_posted_ = false;
  }

  PrefService* pref_service_;

  // True if the task that schedules the writing of the lossy prefs has been
  // posted.
  bool lossy_prefs_writing_task_posted_;

  THREAD_CHECKER(thread_checker_);

  base::WeakPtrFactory<NetworkQualitiesPrefDelegateImpl> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(NetworkQualitiesPrefDelegateImpl);
};

}  // namespace

CronetPrefsManager::CronetPrefsManager(
    const std::string& storage_path,
    scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
    scoped_refptr<base::SequencedTaskRunner> file_task_runner,
    bool enable_network_quality_estimator,
    bool enable_host_cache_persistence,
    net::NetLog* net_log,
    net::URLRequestContextBuilder* context_builder)
    : http_server_properties_manager_(nullptr) {
  DCHECK(network_task_runner->BelongsToCurrentThread());
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

#if defined(OS_WIN)
  base::FilePath storage_file_path(
      base::FilePath::FromUTF8Unsafe(storage_path));
#else
  base::FilePath storage_file_path(storage_path);
#endif

  // Make sure storage directory has correct version.
  {
    base::ScopedAllowBlocking allow_blocking;
    InitializeStorageDirectory(storage_file_path);
  }

  base::FilePath filepath =
      storage_file_path.Append(kPrefsDirectoryName).Append(kPrefsFileName);

  json_pref_store_ = new JsonPrefStore(filepath, std::unique_ptr<PrefFilter>(),
                                       file_task_runner);

  // Register prefs and set up the PrefService.
  PrefServiceFactory factory;
  factory.set_user_prefs(json_pref_store_);
  scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple());
  registry->RegisterDictionaryPref(kHttpServerPropertiesPref);

  if (enable_network_quality_estimator) {
    // Use lossy prefs to limit the overhead of reading/writing the prefs.
    registry->RegisterDictionaryPref(kNetworkQualitiesPref,
                                     PrefRegistry::LOSSY_PREF);
  }

  if (enable_host_cache_persistence) {
    registry->RegisterListPref(kHostCachePref);
  }

  {
    base::ScopedAllowBlocking allow_blocking;
    pref_service_ = factory.Create(registry.get());
  }

  http_server_properties_manager_ = new net::HttpServerPropertiesManager(
      std::make_unique<PrefServiceAdapter>(pref_service_.get()), net_log);

  // Passes |http_server_properties_manager_| ownership to |context_builder|.
  // The ownership will be subsequently passed to UrlRequestContext.
  context_builder->SetHttpServerProperties(
      std::unique_ptr<net::HttpServerPropertiesManager>(
          http_server_properties_manager_));
}

CronetPrefsManager::~CronetPrefsManager() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
}

void CronetPrefsManager::SetupNqePersistence(
    net::NetworkQualityEstimator* nqe) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  network_qualities_prefs_manager_ =
      std::make_unique<net::NetworkQualitiesPrefsManager>(
          std::make_unique<NetworkQualitiesPrefDelegateImpl>(
              pref_service_.get()));

  network_qualities_prefs_manager_->InitializeOnNetworkThread(nqe);
}

void CronetPrefsManager::SetupHostCachePersistence(
    net::HostCache* host_cache,
    int host_cache_persistence_delay_ms,
    net::NetLog* net_log) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  host_cache_persistence_manager_ =
      std::make_unique<HostCachePersistenceManager>(
          host_cache, pref_service_.get(), kHostCachePref,
          base::TimeDelta::FromMilliseconds(host_cache_persistence_delay_ms),
          net_log);
}

void CronetPrefsManager::PrepareForShutdown() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (pref_service_)
    pref_service_->CommitPendingWrite();

  // Shutdown managers on the Pref sequence.
  if (network_qualities_prefs_manager_)
    network_qualities_prefs_manager_->ShutdownOnPrefSequence();

  host_cache_persistence_manager_.reset();
}

}  // namespace cronet
