// 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 "net/nqe/network_qualities_prefs_manager.h"

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/optional.h"
#include "base/rand_util.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/nqe/network_quality_estimator.h"

namespace net {

namespace {

// Maximum size of the prefs that hold the qualities of different networks.
// A single entry in the cache consists of three tuples:
// (i)   SSID or MCCMNC of the network. SSID is at most 32 characters in length
//       (but is typically shorter than that). MCCMNC is at most 6 characters
//       long.
// (ii)  Connection type of the network as reported by network
//       change notifier (an enum).
// (iii) Effective connection type of the network (an enum).
constexpr size_t kMaxCacheSize = 20u;

// Parses |value| into a map of NetworkIDs and CachedNetworkQualities,
// and returns the map.
ParsedPrefs ConvertDictionaryValueToMap(const base::DictionaryValue* value) {
  DCHECK_GE(kMaxCacheSize, value->size());

  ParsedPrefs read_prefs;
  for (const auto& it : value->DictItems()) {
    nqe::internal::NetworkID network_id =
        nqe::internal::NetworkID::FromString(it.first);

    std::string effective_connection_type_string;
    const bool effective_connection_type_available =
        it.second.GetAsString(&effective_connection_type_string);
    DCHECK(effective_connection_type_available);

    base::Optional<EffectiveConnectionType> effective_connection_type =
        GetEffectiveConnectionTypeForName(effective_connection_type_string);
    DCHECK(effective_connection_type.has_value());

    nqe::internal::CachedNetworkQuality cached_network_quality(
        effective_connection_type.value_or(EFFECTIVE_CONNECTION_TYPE_UNKNOWN));
    read_prefs[network_id] = cached_network_quality;
  }
  return read_prefs;
}

}  // namespace

NetworkQualitiesPrefsManager::NetworkQualitiesPrefsManager(
    std::unique_ptr<PrefDelegate> pref_delegate)
    : pref_delegate_(std::move(pref_delegate)),
      pref_task_runner_(base::ThreadTaskRunnerHandle::Get()),
      prefs_(pref_delegate_->GetDictionaryValue()),
      network_quality_estimator_(nullptr),
      read_prefs_startup_(ConvertDictionaryValueToMap(prefs_.get())),
      pref_weak_ptr_factory_(this) {
  DCHECK(pref_delegate_);
  DCHECK(pref_task_runner_);
  DCHECK_GE(kMaxCacheSize, prefs_->size());

  pref_weak_ptr_ = pref_weak_ptr_factory_.GetWeakPtr();
}

NetworkQualitiesPrefsManager::~NetworkQualitiesPrefsManager() {
  if (!network_task_runner_)
    return;
  DCHECK(network_task_runner_->RunsTasksInCurrentSequence());
  if (network_quality_estimator_)
    network_quality_estimator_->RemoveNetworkQualitiesCacheObserver(this);
}

void NetworkQualitiesPrefsManager::InitializeOnNetworkThread(
    NetworkQualityEstimator* network_quality_estimator) {
  DCHECK(!network_task_runner_);
  DCHECK(network_quality_estimator);

  network_task_runner_ = base::ThreadTaskRunnerHandle::Get();
  network_quality_estimator_ = network_quality_estimator;
  network_quality_estimator_->AddNetworkQualitiesCacheObserver(this);

  // Notify network quality estimator of the read prefs.
  network_quality_estimator_->OnPrefsRead(read_prefs_startup_);
}

void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQuality(
    const nqe::internal::NetworkID& network_id,
    const nqe::internal::CachedNetworkQuality& cached_network_quality) {
  DCHECK(network_task_runner_->RunsTasksInCurrentSequence());

  // Notify |this| on the pref thread.
  pref_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&NetworkQualitiesPrefsManager::
                     OnChangeInCachedNetworkQualityOnPrefSequence,
                 pref_weak_ptr_, network_id, cached_network_quality));
}

void NetworkQualitiesPrefsManager::ShutdownOnPrefSequence() {
  DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
  pref_weak_ptr_factory_.InvalidateWeakPtrs();
  pref_delegate_.reset();
}

void NetworkQualitiesPrefsManager::ClearPrefs() {
  DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
  prefs_->Clear();
  DCHECK_EQ(0u, prefs_->size());
  pref_delegate_->SetDictionaryValue(*prefs_);
}

void NetworkQualitiesPrefsManager::OnChangeInCachedNetworkQualityOnPrefSequence(
    const nqe::internal::NetworkID& network_id,
    const nqe::internal::CachedNetworkQuality& cached_network_quality) {
  // The prefs can only be written on the pref thread.
  DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
  DCHECK_GE(kMaxCacheSize, prefs_->size());

  std::string network_id_string = network_id.ToString();

  // If the network ID contains a period, then return early since the dictionary
  // prefs cannot contain period in the path.
  if (network_id_string.find('.') != std::string::npos)
    return;

  prefs_->SetString(network_id_string,
                    GetNameForEffectiveConnectionType(
                        cached_network_quality.effective_connection_type()));

  if (prefs_->size() > kMaxCacheSize) {
    // Delete one randomly selected value that has a key that is different from
    // |network_id|.
    DCHECK_EQ(kMaxCacheSize + 1, prefs_->size());
    // Generate a random number in the range [0, |kMaxCacheSize| - 1] since the
    // number of network IDs in |prefs_| other than |network_id| is
    // |kMaxCacheSize|.
    int index_to_delete = base::RandInt(0, kMaxCacheSize - 1);

    for (const auto& it : prefs_->DictItems()) {
      // Delete the kth element in the dictionary, not including the element
      // that represents the current network. k == |index_to_delete|.
      if (nqe::internal::NetworkID::FromString(it.first) == network_id)
        continue;

      if (index_to_delete == 0) {
        prefs_->RemoveKey(it.first);
        break;
      }
      index_to_delete--;
    }
  }
  DCHECK_GE(kMaxCacheSize, prefs_->size());

  // Notify the pref delegate so that it updates the prefs on the disk.
  pref_delegate_->SetDictionaryValue(*prefs_);
}

ParsedPrefs NetworkQualitiesPrefsManager::ForceReadPrefsForTesting() const {
  DCHECK(pref_task_runner_->RunsTasksInCurrentSequence());
  std::unique_ptr<base::DictionaryValue> value(
      pref_delegate_->GetDictionaryValue());
  return ConvertDictionaryValueToMap(value.get());
}

}  // namespace net
