// 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 "base/deferred_sequenced_task_runner.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_impl.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/network_service_util.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality_estimator.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "services/network/public/mojom/network_service_test.mojom.h"
#include "services/service_manager/public/cpp/connector.h"

namespace network {

namespace {

// Simulates a network quality change. This is only called when network service
// is running in the browser process, in which case, the network quality
// estimator lives on the network thread (which will be the IO thread if network
// service is disabled).
void SimulateNetworkQualityChangeOnNetworkThread(
    net::EffectiveConnectionType type) {
  if (content::IsInProcessNetworkService()) {
    network::NetworkService::GetNetworkServiceForTesting()
        ->network_quality_estimator()
        ->SimulateNetworkQualityChangeForTesting(type);
  } else {
    DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
    DCHECK(content::GetNetworkServiceImpl());
    DCHECK(content::GetNetworkServiceImpl()->network_quality_estimator());
    content::GetNetworkServiceImpl()
        ->network_quality_estimator()
        ->SimulateNetworkQualityChangeForTesting(type);
  }
  base::RunLoop().RunUntilIdle();
}

class TestNetworkQualityObserver
    : public NetworkQualityTracker::EffectiveConnectionTypeObserver {
 public:
  explicit TestNetworkQualityObserver(NetworkQualityTracker* tracker)
      : num_notifications_(0),
        run_loop_wait_effective_connection_type_(
            net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
        run_loop_(std::make_unique<base::RunLoop>()),
        tracker_(tracker),
        effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
    tracker_->AddEffectiveConnectionTypeObserver(this);
  }

  ~TestNetworkQualityObserver() override {
    tracker_->RemoveEffectiveConnectionTypeObserver(this);
  }

  // NetworkQualityTracker::EffectiveConnectionTypeObserver implementation:
  void OnEffectiveConnectionTypeChanged(
      net::EffectiveConnectionType type) override {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

    net::EffectiveConnectionType queried_type =
        tracker_->GetEffectiveConnectionType();
    EXPECT_EQ(type, queried_type);

    num_notifications_++;
    effective_connection_type_ = type;
    if (effective_connection_type_ != run_loop_wait_effective_connection_type_)
      return;
    run_loop_->Quit();
  }

  void WaitForNotification(
      net::EffectiveConnectionType run_loop_wait_effective_connection_type) {
    if (effective_connection_type_ == run_loop_wait_effective_connection_type)
      return;
    ASSERT_NE(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
              run_loop_wait_effective_connection_type);
    run_loop_wait_effective_connection_type_ =
        run_loop_wait_effective_connection_type;
    run_loop_->Run();
    run_loop_.reset(new base::RunLoop());
  }

  size_t num_notifications() const { return num_notifications_; }
  net::EffectiveConnectionType effective_connection_type() const {
    return effective_connection_type_;
  }
  base::TimeDelta http_rtt() const { return tracker_->GetHttpRTT(); }
  base::TimeDelta transport_rtt() const { return tracker_->GetTransportRTT(); }
  int32_t downlink_bandwidth_kbps() const {
    return tracker_->GetDownstreamThroughputKbps();
  }

 private:
  size_t num_notifications_;
  net::EffectiveConnectionType run_loop_wait_effective_connection_type_;
  std::unique_ptr<base::RunLoop> run_loop_;
  NetworkQualityTracker* tracker_;
  net::EffectiveConnectionType effective_connection_type_;

  DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityObserver);
};

}  // namespace

class NetworkQualityTrackerBrowserTest : public InProcessBrowserTest {
 public:
  NetworkQualityTrackerBrowserTest() {}
  ~NetworkQualityTrackerBrowserTest() override {}

  // Simulates a network quality change.
  void SimulateNetworkQualityChange(net::EffectiveConnectionType type) {
    if (!content::IsOutOfProcessNetworkService()) {
      scoped_refptr<base::SequencedTaskRunner> task_runner =
          base::CreateSequencedTaskRunnerWithTraits(
              {content::BrowserThread::IO});
      if (content::IsInProcessNetworkService())
        task_runner = content::GetNetworkTaskRunner();
      task_runner->PostTask(
          FROM_HERE,
          base::BindOnce(&SimulateNetworkQualityChangeOnNetworkThread, type));
      return;
    }

    mojo::ScopedAllowSyncCallForTesting allow_sync_call;
    content::StoragePartition* partition =
        content::BrowserContext::GetDefaultStoragePartition(
            browser()->profile());
    DCHECK(partition->GetNetworkContext());
    DCHECK(content::GetNetworkService());

    network::mojom::NetworkServiceTestPtr network_service_test;
    content::ServiceManagerConnection::GetForProcess()
        ->GetConnector()
        ->BindInterface(content::mojom::kNetworkServiceName,
                        &network_service_test);
    base::RunLoop run_loop;
    network_service_test->SimulateNetworkQualityChange(
        type, base::BindOnce([](base::RunLoop* run_loop) { run_loop->Quit(); },
                             base::Unretained(&run_loop)));
    run_loop.Run();
  }
};

// Basic test to make sure NetworkQualityTracker is set up, and observers are
// notified.
IN_PROC_BROWSER_TEST_F(NetworkQualityTrackerBrowserTest,
                       NetworkQualityTracker) {
  // Change the network quality to UNKNOWN to prevent any spurious
  // notifications.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  base::RunLoop().RunUntilIdle();

  NetworkQualityTracker* tracker = g_browser_process->network_quality_tracker();
  EXPECT_NE(nullptr, tracker);

  base::RunLoop run_loop;
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_4G);
  TestNetworkQualityObserver network_quality_observer(tracker);
  network_quality_observer.WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_4G);
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_4G,
            network_quality_observer.effective_connection_type());

  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
  network_quality_observer.WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_3G);
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G,
            network_quality_observer.effective_connection_type());

  base::RunLoop().RunUntilIdle();

  // Verify that not too many effective connection type observations are
  // received. Note that setting the effective connection type to UNKNOWN above,
  // and adding the observer is racy. In some cases, the observer may receiver
  // the notification about effective connection type being UNKNOWN, followed
  // by other notifications.
  EXPECT_LE(1u, network_quality_observer.num_notifications());
  EXPECT_GE(5u, network_quality_observer.num_notifications());

  // Typical RTT and downlink values when effective connection type is 3G. Taken
  // from net::NetworkQualityEstimatorParams.
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(450),
            network_quality_observer.http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(400),
            network_quality_observer.transport_rtt());
  EXPECT_EQ(400, network_quality_observer.downlink_bandwidth_kbps());
}

// Basic test to make sure NetworkQualityTracker is set up, and clients are
// notified as soon as they request notifications from the
// NetworkQualityEstimatorManager.
IN_PROC_BROWSER_TEST_F(NetworkQualityTrackerBrowserTest,
                       NetworkQualityTrackerNotifiedOnInitialization) {
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
  base::RunLoop().RunUntilIdle();

  NetworkQualityTracker* tracker = g_browser_process->network_quality_tracker();
  EXPECT_NE(nullptr, tracker);

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

// Simulates a network service crash, and ensures that network quality estimate
// manager binds to the restarted network service.
IN_PROC_BROWSER_TEST_F(NetworkQualityTrackerBrowserTest,
                       SimulateNetworkServiceCrash) {
  // Network service is not running out of process, so cannot be crashed.
  if (!content::IsOutOfProcessNetworkService())
    return;

  // Change the network quality to UNKNOWN to prevent any spurious
  // notifications.
  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  base::RunLoop().RunUntilIdle();

  NetworkQualityTracker* tracker = g_browser_process->network_quality_tracker();
  EXPECT_NE(nullptr, tracker);

  base::RunLoop run_loop;
  TestNetworkQualityObserver network_quality_observer(tracker);
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
            network_quality_observer.effective_connection_type());

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

  SimulateNetworkServiceCrash();
  // Flush the network interface to make sure it notices the crash.
  content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
      ->FlushNetworkInterfaceForTesting();

  base::RunLoop().RunUntilIdle();

  SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
  network_quality_observer.WaitForNotification(
      net::EFFECTIVE_CONNECTION_TYPE_2G);
  EXPECT_LE(2u, network_quality_observer.num_notifications());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1800),
            network_quality_observer.http_rtt());
  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1500),
            network_quality_observer.transport_rtt());
  EXPECT_EQ(75, network_quality_observer.downlink_bandwidth_kbps());
}

}  // namespace network
