// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/network_change_notifier_linux.h"

#include <string>

#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread.h"
#include "net/base/address_tracker_linux.h"
#include "net/dns/dns_config_service_posix.h"

namespace net {

// A collection of objects that live on blocking threads.
class NetworkChangeNotifierLinux::BlockingThreadObjects {
 public:
  explicit BlockingThreadObjects(
      const std::unordered_set<std::string>& ignored_interfaces,
      scoped_refptr<base::SequencedTaskRunner> blocking_thread_runner);
  BlockingThreadObjects(const BlockingThreadObjects&) = delete;
  BlockingThreadObjects& operator=(const BlockingThreadObjects&) = delete;

  // Plumbing for NetworkChangeNotifier::GetCurrentConnectionType.
  // Safe to call from any thread.
  NetworkChangeNotifier::ConnectionType GetCurrentConnectionType() {
    return address_tracker_.GetCurrentConnectionType();
  }

  internal::AddressTrackerLinux* address_tracker() { return &address_tracker_; }

  // Begin watching for netlink changes.
  void Init();

  void InitForTesting(base::ScopedFD netlink_fd);  // IN-TEST

 private:
  void OnIPAddressChanged(IPAddressChangeType change_type);
  void OnLinkChanged();
  // Used to detect online/offline state and IP address changes.
  internal::AddressTrackerLinux address_tracker_;
  NetworkChangeNotifier::ConnectionType last_type_ =
      NetworkChangeNotifier::CONNECTION_NONE;
};

NetworkChangeNotifierLinux::BlockingThreadObjects::BlockingThreadObjects(
    const std::unordered_set<std::string>& ignored_interfaces,
    scoped_refptr<base::SequencedTaskRunner> blocking_thread_runner)
    : address_tracker_(
          base::BindRepeating(&NetworkChangeNotifierLinux::
                                  BlockingThreadObjects::OnIPAddressChanged,
                              base::Unretained(this)),
          base::BindRepeating(
              &NetworkChangeNotifierLinux::BlockingThreadObjects::OnLinkChanged,
              base::Unretained(this)),
          base::DoNothing(),
          ignored_interfaces,
          std::move(blocking_thread_runner)) {}

void NetworkChangeNotifierLinux::BlockingThreadObjects::Init() {
  address_tracker_.Init();
  last_type_ = GetCurrentConnectionType();
}

void NetworkChangeNotifierLinux::BlockingThreadObjects::InitForTesting(
    base::ScopedFD netlink_fd) {
  address_tracker_.InitWithFdForTesting(std::move(netlink_fd));  // IN-TEST
  last_type_ = GetCurrentConnectionType();
}

void NetworkChangeNotifierLinux::BlockingThreadObjects::OnIPAddressChanged(
    IPAddressChangeType change_type) {
  NetworkChangeNotifier::NotifyObserversOfIPAddressChange(change_type);
  // When the IP address of a network interface is added/deleted, the
  // connection type may have changed.
  OnLinkChanged();
}

void NetworkChangeNotifierLinux::BlockingThreadObjects::OnLinkChanged() {
  if (last_type_ != GetCurrentConnectionType()) {
    NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange();
    last_type_ = GetCurrentConnectionType();
    double max_bandwidth_mbps =
        NetworkChangeNotifier::GetMaxBandwidthMbpsForConnectionSubtype(
            last_type_ == CONNECTION_NONE ? SUBTYPE_NONE : SUBTYPE_UNKNOWN);
    NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChange(
        max_bandwidth_mbps, last_type_);
  }
}

// static
std::unique_ptr<NetworkChangeNotifierLinux>
NetworkChangeNotifierLinux::CreateWithSocketForTesting(
    const std::unordered_set<std::string>& ignored_interfaces,
    base::ScopedFD netlink_fd) {
  auto ncn_linux = std::make_unique<NetworkChangeNotifierLinux>(
      ignored_interfaces, /*initialize_blocking_thread_objects=*/false,
      base::PassKey<NetworkChangeNotifierLinux>());
  ncn_linux->InitBlockingThreadObjectsForTesting(  // IN-TEST
      std::move(netlink_fd));
  return ncn_linux;
}

NetworkChangeNotifierLinux::NetworkChangeNotifierLinux(
    const std::unordered_set<std::string>& ignored_interfaces)
    : NetworkChangeNotifierLinux(ignored_interfaces,
                                 /*initialize_blocking_thread_objects*/ true,
                                 base::PassKey<NetworkChangeNotifierLinux>()) {}

NetworkChangeNotifierLinux::NetworkChangeNotifierLinux(
    const std::unordered_set<std::string>& ignored_interfaces,
    bool initialize_blocking_thread_objects,
    base::PassKey<NetworkChangeNotifierLinux>)
    : NetworkChangeNotifier(NetworkChangeCalculatorParamsLinux()),
      blocking_thread_runner_(
          base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})),
      blocking_thread_objects_(
          new BlockingThreadObjects(ignored_interfaces,
                                    blocking_thread_runner_),
          // Ensure |blocking_thread_objects_| lives on
          // |blocking_thread_runner_| to prevent races where
          // NetworkChangeNotifierLinux outlives
          // TaskEnvironment. https://crbug.com/938126
          base::OnTaskRunnerDeleter(blocking_thread_runner_)) {
  if (initialize_blocking_thread_objects) {
    blocking_thread_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&NetworkChangeNotifierLinux::BlockingThreadObjects::Init,
                       // The Unretained pointer is safe here because it's
                       // posted before the deleter can post.
                       base::Unretained(blocking_thread_objects_.get())));
  }
}

NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() {
  ClearGlobalPointer();
}

// static
NetworkChangeNotifier::NetworkChangeCalculatorParams
NetworkChangeNotifierLinux::NetworkChangeCalculatorParamsLinux() {
  NetworkChangeCalculatorParams params;
  // Delay values arrived at by simple experimentation and adjusted so as to
  // produce a single signal when switching between network connections.
  params.ip_address_offline_delay_ = base::Milliseconds(2000);
  params.ip_address_online_delay_ = base::Milliseconds(2000);
  params.connection_type_offline_delay_ = base::Milliseconds(1500);
  params.connection_type_online_delay_ = base::Milliseconds(500);
  return params;
}

void NetworkChangeNotifierLinux::InitBlockingThreadObjectsForTesting(
    base::ScopedFD netlink_fd) {
  DCHECK(blocking_thread_objects_);
  blocking_thread_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(
          &NetworkChangeNotifierLinux::BlockingThreadObjects::InitForTesting,
          // The Unretained pointer is safe here because it's
          // posted before the deleter can post.
          base::Unretained(blocking_thread_objects_.get()),
          std::move(netlink_fd)));
}

NetworkChangeNotifier::ConnectionType
NetworkChangeNotifierLinux::GetCurrentConnectionType() const {
  return blocking_thread_objects_->GetCurrentConnectionType();
}

AddressMapOwnerLinux* NetworkChangeNotifierLinux::GetAddressMapOwnerInternal() {
  return blocking_thread_objects_->address_tracker();
}

}  // namespace net
