// Copyright 2018 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 "services/network/network_quality_estimator_manager.h"

#include <algorithm>
#include <utility>

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "net/log/test_net_log.h"
#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality_estimator.h"
#include "services/network/public/mojom/network_quality_estimator_manager.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace network {

namespace {

class TestNetworkQualityEstimatorManagerClient
    : public mojom::NetworkQualityEstimatorManagerClient {
 public:
  explicit TestNetworkQualityEstimatorManagerClient(
      NetworkQualityEstimatorManager* network_quality_estimator_manager)
      : network_quality_estimator_manager_(network_quality_estimator_manager),
        num_network_quality_changed_(0),
        run_loop_(std::make_unique<base::RunLoop>()),
        effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
        http_rtt_(base::TimeDelta()),
        transport_rtt_(base::TimeDelta()),
        downlink_bandwidth_kbps_(INT32_MAX),
        binding_(this) {
    mojom::NetworkQualityEstimatorManagerPtr manager_ptr;
    mojom::NetworkQualityEstimatorManagerRequest request(
        mojo::MakeRequest(&manager_ptr));
    network_quality_estimator_manager_->AddRequest(std::move(request));

    mojom::NetworkQualityEstimatorManagerClientPtr client_ptr;
    mojom::NetworkQualityEstimatorManagerClientRequest client_request(
        mojo::MakeRequest(&client_ptr));
    binding_.Bind(std::move(client_request));
    manager_ptr->RequestNotifications(std::move(client_ptr));
  }

  ~TestNetworkQualityEstimatorManagerClient() override {}

  void OnNetworkQualityChanged(net::EffectiveConnectionType type,
                               base::TimeDelta http_rtt,
                               base::TimeDelta transport_rtt,
                               int32_t downlink_bandwidth_kbps) override {
    num_network_quality_changed_++;
    effective_connection_type_ = type;
    http_rtt_ = http_rtt;
    transport_rtt_ = transport_rtt;
    downlink_bandwidth_kbps_ = downlink_bandwidth_kbps;
    if (run_loop_wait_effective_connection_type_ == type)
      run_loop_->Quit();
  }

  // Returns the number of OnNetworkQualityChanged() notifications. Note that
  // the number may change based on the order in which underlying network
  // quality estimator provides notifications when effective connection
  // type, RTT and downlink estimates change simultaneously.
  size_t num_network_quality_changed() const {
    return num_network_quality_changed_;
  }

  void WaitForNotification(
      net::EffectiveConnectionType effective_connection_type) {
    run_loop_wait_effective_connection_type_ = effective_connection_type;
    run_loop_->Run();
    run_loop_.reset(new base::RunLoop());
  }

  net::EffectiveConnectionType effective_connection_type() const {
    return effective_connection_type_;
  }
  base::TimeDelta http_rtt() const { return http_rtt_; }
  base::TimeDelta transport_rtt() const { return transport_rtt_; }
  int32_t downlink_bandwidth_kbps() const { return downlink_bandwidth_kbps_; }

 private:
  NetworkQualityEstimatorManager* network_quality_estimator_manager_;
  size_t num_network_quality_changed_;
  std::unique_ptr<base::RunLoop> run_loop_;
  net::EffectiveConnectionType run_loop_wait_effective_connection_type_;
  net::EffectiveConnectionType effective_connection_type_;
  base::TimeDelta http_rtt_;
  base::TimeDelta transport_rtt_;
  int32_t downlink_bandwidth_kbps_;
  mojo::Binding<mojom::NetworkQualityEstimatorManagerClient> binding_;

  DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimatorManagerClient);
};

}  // namespace

class NetworkQualityEstimatorManagerTest : public testing::Test {
 public:
  NetworkQualityEstimatorManagerTest()
      : net_log_(std::make_unique<net::BoundTestNetLog>()),
        network_quality_estimator_manager_(
            std::make_unique<NetworkQualityEstimatorManager>(
                net_log_->bound().net_log())) {
    // Change the network quality to UNKNOWN to prevent any spurious
    // notifications.
    SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
    network_quality_estimator_manager_client_ =
        std::make_unique<TestNetworkQualityEstimatorManagerClient>(
            network_quality_estimator_manager_.get());
  }

  ~NetworkQualityEstimatorManagerTest() override {}

  TestNetworkQualityEstimatorManagerClient*
  network_quality_estimator_manager_client() {
    return network_quality_estimator_manager_client_.get();
  }

  NetworkQualityEstimatorManager* network_quality_estimator_manager() const {
    return network_quality_estimator_manager_.get();
  }

  void SimulateNetworkQualityChange(net::EffectiveConnectionType type) {
    network_quality_estimator_manager_->GetNetworkQualityEstimator()
        ->SimulateNetworkQualityChangeForTesting(type);
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<net::BoundTestNetLog> net_log_;
  std::unique_ptr<NetworkQualityEstimatorManager>
      network_quality_estimator_manager_;
  std::unique_ptr<TestNetworkQualityEstimatorManagerClient>
      network_quality_estimator_manager_client_;

  DISALLOW_COPY_AND_ASSIGN(NetworkQualityEstimatorManagerTest);
};

TEST_F(NetworkQualityEstimatorManagerTest, ClientNotified) {
  // Simulate a new network quality change.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_3G);
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_3G,
      network_quality_estimator_manager_client()->effective_connection_type());
  base::RunLoop().RunUntilIdle();
  // Verify that not more than 2 notifications were received.
  EXPECT_GE(2u, network_quality_estimator_manager_client()
                    ->num_network_quality_changed());
  // Typical RTT and downlink values when effective connection type is 3G. Taken
  // from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
            network_quality_estimator_manager_client()->http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      400,
      network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
}

// Test that when the network quality is unavailable, network quality estimator
// manager reports the estimated network quality values as negative.
TEST_F(NetworkQualityEstimatorManagerTest,
       ClientNotifiedUnknownNetworkQuality) {
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
      network_quality_estimator_manager_client()->effective_connection_type());
  base::RunLoop().RunUntilIdle();

  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_3G);
  base::RunLoop().RunUntilIdle();
  // Typical RTT and downlink values when effective connection type is 3G. Taken
  // from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
            network_quality_estimator_manager_client()->http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      400,
      network_quality_estimator_manager_client()->downlink_bandwidth_kbps());

  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  base::RunLoop().RunUntilIdle();
  EXPECT_GT(base::TimeDelta(),
            network_quality_estimator_manager_client()->http_rtt());
  EXPECT_GT(base::TimeDelta(),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_GT(
      0, network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
}

TEST_F(NetworkQualityEstimatorManagerTest, OneClientPipeBroken) {
  auto network_quality_estimator_manager_client2 =
      std::make_unique<TestNetworkQualityEstimatorManagerClient>(
          network_quality_estimator_manager());

  // Simulate a network quality change.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_4G);

  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_4G);
  network_quality_estimator_manager_client2->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_4G);
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_4G,
      network_quality_estimator_manager_client()->effective_connection_type());
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_4G,
      network_quality_estimator_manager_client2->effective_connection_type());
  // Typical RTT and downlink values when effective connection type is 4G. Taken
  // from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(175),
            network_quality_estimator_manager_client2->http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(125),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      1600,
      network_quality_estimator_manager_client2->downlink_bandwidth_kbps());
  base::RunLoop().RunUntilIdle();

  EXPECT_GE(2u, network_quality_estimator_manager_client()
                    ->num_network_quality_changed());
  EXPECT_GE(
      2u,
      network_quality_estimator_manager_client2->num_network_quality_changed());
  network_quality_estimator_manager_client2.reset();

  base::RunLoop().RunUntilIdle();

  // Simulate a second network quality change, and the remaining client should
  // be notified.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);

  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_2G);
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_2G,
      network_quality_estimator_manager_client()->effective_connection_type());
  EXPECT_GE(3u, network_quality_estimator_manager_client()
                    ->num_network_quality_changed());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
            network_quality_estimator_manager_client()->http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      75,
      network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
}

TEST_F(NetworkQualityEstimatorManagerTest,
       NewClientReceivesCurrentEffectiveType) {
  // Simulate a network quality change.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);

  network_quality_estimator_manager_client()->WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_2G);
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_2G,
      network_quality_estimator_manager_client()->effective_connection_type());
  base::RunLoop().RunUntilIdle();
  // Typical RTT and downlink values when effective connection type is 2G. Taken
  // from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
            network_quality_estimator_manager_client()->http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      75,
      network_quality_estimator_manager_client()->downlink_bandwidth_kbps());

  // Register a new client after the network quality change and it should
  // receive the up-to-date effective connection type.
  TestNetworkQualityEstimatorManagerClient
      network_quality_estimator_manager_client2(
          network_quality_estimator_manager());
  network_quality_estimator_manager_client2.WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_2G);
  EXPECT_EQ(
      net::EFFECTIVE_CONNECTION_TYPE_2G,
      network_quality_estimator_manager_client2.effective_connection_type());
  // Typical RTT and downlink values when when effective connection type is 2G.
  // Taken from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
            network_quality_estimator_manager_client2.http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
            network_quality_estimator_manager_client()->transport_rtt());
  EXPECT_EQ(
      75, network_quality_estimator_manager_client2.downlink_bandwidth_kbps());
}

}  // namespace network
