// 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 <algorithm>
#include <map>
#include <memory>

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "net/base/network_change_notifier.h"
#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_id.h"
#include "net/nqe/network_quality_estimator_test_util.h"
#include "net/nqe/network_quality_store.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class TestPrefDelegate : public NetworkQualitiesPrefsManager::PrefDelegate {
 public:
  TestPrefDelegate()
      : write_count_(0), read_count_(0), value_(new base::DictionaryValue) {}

  ~TestPrefDelegate() override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    value_->Clear();
    EXPECT_EQ(0U, value_->size());
  }

  void SetDictionaryValue(const base::DictionaryValue& value) override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    write_count_++;
    value_.reset(value.DeepCopy());
    ASSERT_EQ(value.size(), value_->size());
  }

  std::unique_ptr<base::DictionaryValue> GetDictionaryValue() override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    read_count_++;
    return value_->CreateDeepCopy();
  }

  size_t write_count() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return write_count_;
  }

  size_t read_count() const {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return read_count_;
  }

 private:
  // Number of times prefs were written and read, respectively..
  size_t write_count_;
  size_t read_count_;

  // Current value of the prefs.
  std::unique_ptr<base::DictionaryValue> value_;

  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(TestPrefDelegate);
};

using NetworkQualitiesPrefManager = TestWithScopedTaskEnvironment;

TEST_F(NetworkQualitiesPrefManager, Write) {
  // Force set the ECT to Slow 2G so that the ECT does not match the default
  // ECT for the current connection type. This forces the prefs to be written
  // for the current connection.
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "Slow-2G";
  TestNetworkQualityEstimator estimator(variation_params);

  std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
  TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();

  NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
  manager.InitializeOnNetworkThread(&estimator);
  base::RunLoop().RunUntilIdle();

  // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());

  estimator.SimulateNetworkChange(
      NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
  EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
  // Network quality generated from the default observation must be written.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, prefs_delegate_ptr->write_count());

  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality.
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(4u, prefs_delegate_ptr->write_count());

  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality..
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(5u, prefs_delegate_ptr->write_count());

  // Prefs should not be read again.
  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());

  manager.ShutdownOnPrefSequence();
}

TEST_F(NetworkQualitiesPrefManager, WriteWhenMatchingExpectedECT) {
  // Force set the ECT to Slow 2G so that the ECT does not match the default
  // ECT for the current connection type. This forces the prefs to be written
  // for the current connection.
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "Slow-2G";
  TestNetworkQualityEstimator estimator(variation_params);

  std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());
  TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();

  NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
  manager.InitializeOnNetworkThread(&estimator);
  base::RunLoop().RunUntilIdle();

  // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());

  const nqe::internal::NetworkID network_id(
      NetworkChangeNotifier::ConnectionType::CONNECTION_4G, "test", INT32_MIN);

  estimator.SimulateNetworkChange(network_id.type, network_id.id);
  EXPECT_EQ(1u, prefs_delegate_ptr->write_count());
  // Network quality generated from the default observation must be written.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, prefs_delegate_ptr->write_count());

  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality.
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(4u, prefs_delegate_ptr->write_count());

  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality..
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(5u, prefs_delegate_ptr->write_count());

  // Prefs should not be read again.
  EXPECT_EQ(1u, prefs_delegate_ptr->read_count());

  EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
  EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_3G,
            manager.ForceReadPrefsForTesting()
                .find(network_id)
                ->second.effective_connection_type());

  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_4G);
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();

  // Network Quality should be persisted to disk even if it matches the typical
  // quality of the network. See crbug.com/890859.
  EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
  EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().count(network_id));
  EXPECT_EQ(6u, prefs_delegate_ptr->write_count());

  manager.ShutdownOnPrefSequence();
}

TEST_F(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
  static const size_t kMaxCacheSize = 20u;

  // Force set the ECT to Slow 2G so that the ECT does not match the default
  // ECT for the current connection type. This forces the prefs to be written
  // for the current connection.
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "Slow-2G";
  TestNetworkQualityEstimator estimator(variation_params);

  std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());

  NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
  manager.InitializeOnNetworkThread(&estimator);
  base::RunLoop().RunUntilIdle();

  estimator.SimulateNetworkChange(
      NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");

  EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());

  estimator.set_recent_effective_connection_type(
      EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality.
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  // Verify that the observer was notified, and the updated network quality was
  // written to the prefs.
  EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());

  // Change the network ID.
  for (size_t i = 0; i < kMaxCacheSize; ++i) {
    estimator.SimulateNetworkChange(
        NetworkChangeNotifier::ConnectionType::CONNECTION_2G,
        "test" + base::IntToString(i));

    estimator.RunOneRequest();
    base::RunLoop().RunUntilIdle();

    EXPECT_EQ(std::min(i + 3, kMaxCacheSize),
              manager.ForceReadPrefsForTesting().size());
  }

  std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality>
      read_prefs = manager.ForceReadPrefsForTesting();

  // Verify the contents of the prefs.
  size_t count_2g_entries = 0;
  for (std::map<nqe::internal::NetworkID,
                nqe::internal::CachedNetworkQuality>::const_iterator it =
           read_prefs.begin();
       it != read_prefs.end(); ++it) {
    if (it->first.type ==
        NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN) {
      continue;
    }
    EXPECT_EQ(0u, it->first.id.find("test", 0u));
    EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_2G,
              it->first.type);
    EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
              it->second.effective_connection_type());
    ++count_2g_entries;
  }

  // At most one entry should be for the network with connection type
  // NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN.
  EXPECT_LE(kMaxCacheSize - 1, count_2g_entries);

  base::HistogramTester histogram_tester;
  estimator.OnPrefsRead(read_prefs);
  histogram_tester.ExpectUniqueSample("NQE.Prefs.ReadSize", kMaxCacheSize, 1);

  manager.ShutdownOnPrefSequence();
}

// Verifies that the prefs are cleared correctly.
TEST_F(NetworkQualitiesPrefManager, ClearPrefs) {
  // Force set the ECT to Slow 2G so that the ECT does not match the default
  // ECT for the current connection type. This forces the prefs to be written
  // for the current connection.
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "Slow-2G";
  TestNetworkQualityEstimator estimator(variation_params);

  std::unique_ptr<TestPrefDelegate> prefs_delegate(new TestPrefDelegate());

  NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
  manager.InitializeOnNetworkThread(&estimator);
  base::RunLoop().RunUntilIdle();

  estimator.SimulateNetworkChange(
      NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");

  EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());

  estimator.set_recent_effective_connection_type(
      EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality.
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  // Verify that the observer was notified, and the updated network quality was
  // written to the prefs.
  EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());

  // Prefs must be completely cleared.
  manager.ClearPrefs();
  EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().size());
  estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
  // Run a request so that effective connection type is recomputed, and
  // observers are notified of change in the network quality.
  estimator.RunOneRequest();
  base::RunLoop().RunUntilIdle();
  // Verify that the observer was notified, and the updated network quality was
  // written to the prefs.
  EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
  manager.ShutdownOnPrefSequence();
}

}  // namespace

}  // namespace net
