/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/network.h"

#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/sequence_checker.h"
#include "api/test/rtc_error_matchers.h"
#include "rtc_base/checks.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/logging.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/net_test_helpers.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/network_monitor.h"
#include "rtc_base/network_monitor_factory.h"
#include "rtc_base/physical_socket_server.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/thread.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

// IWYU pragma: begin_keep
#if defined(WEBRTC_POSIX)
#include <net/if.h>
#include <sys/types.h>
#include <unistd.h>

#include "rtc_base/ifaddrs_converter.h"
#endif  // defined(WEBRTC_POSIX)
// IWYU pragma: end_keep

using ::testing::Contains;
using ::testing::IsTrue;
using ::testing::Not;
using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;

#define MAYBE_SKIP_IPV4                        \
  if (!::webrtc::HasIPv4Enabled()) {           \
    RTC_LOG(LS_INFO) << "No IPv4... skipping"; \
    return;                                    \
  }

namespace webrtc {

namespace {

IPAddress IPFromString(absl::string_view str) {
  IPAddress ip;
  RTC_CHECK(IPFromString(str, &ip));
  return ip;
}

class FakeNetworkMonitor : public NetworkMonitorInterface {
 public:
  void Start() override { started_ = true; }
  void Stop() override { started_ = false; }
  bool started() { return started_; }
  InterfaceInfo GetInterfaceInfo(absl::string_view if_name) override {
    InterfaceInfo if_info = {
        .adapter_type = ADAPTER_TYPE_UNKNOWN,
        .available = absl::c_count(unavailable_adapters_, if_name) == 0,
    };
    if (absl::StartsWith(if_name, "wifi")) {
      if_info.adapter_type = ADAPTER_TYPE_WIFI;
    } else if (absl::StartsWith(if_name, "cellular")) {
      if_info.adapter_type = ADAPTER_TYPE_CELLULAR;
    }
    return if_info;
  }

  // Used to test IsAdapterAvailable.
  void set_unavailable_adapters(std::vector<std::string> unavailable_adapters) {
    unavailable_adapters_ = unavailable_adapters;
  }

  bool SupportsBindSocketToNetwork() const override { return true; }

  NetworkBindingResult BindSocketToNetwork(int socket_fd,
                                           const IPAddress& address,
                                           absl::string_view if_name) override {
    if (absl::c_count(addresses_, address) > 0) {
      return NetworkBindingResult::SUCCESS;
    }

    for (auto const& iter : adapters_) {
      if (absl::StrContains(if_name, iter)) {
        return NetworkBindingResult::SUCCESS;
      }
    }
    return NetworkBindingResult::ADDRESS_NOT_FOUND;
  }

  void set_ip_addresses(std::vector<IPAddress> addresses) {
    addresses_ = addresses;
  }

  void set_adapters(std::vector<std::string> adapters) { adapters_ = adapters; }

  void InovkeNetworksChangedCallbackForTesting() {
    InvokeNetworksChangedCallback();
  }

 private:
  bool started_ = false;
  std::vector<std::string> adapters_;
  std::vector<std::string> unavailable_adapters_;
  std::vector<IPAddress> addresses_;
};

class FakeNetworkMonitorFactory : public NetworkMonitorFactory {
 public:
  FakeNetworkMonitorFactory() {}
  NetworkMonitorInterface* CreateNetworkMonitor(
      const FieldTrialsView& field_trials) override {
    return new FakeNetworkMonitor();
  }
};

bool SameNameAndPrefix(const Network& a, const Network& b) {
  if (a.name() != b.name()) {
    RTC_LOG(LS_INFO) << "Different interface names.";
    return false;
  }
  if (a.prefix_length() != b.prefix_length() || a.prefix() != b.prefix()) {
    RTC_LOG(LS_INFO) << "Different IP prefixes.";
    return false;
  }
  return true;
}

std::vector<const Network*> CopyNetworkPointers(
    const std::vector<std::unique_ptr<Network>>& owning_list) {
  std::vector<const Network*> ptr_list;
  ptr_list.reserve(owning_list.size());
  for (const auto& network : owning_list) {
    ptr_list.push_back(network.get());
  }
  return ptr_list;
}

}  // namespace

class NetworkTest : public ::testing::Test {
 public:
  void OnNetworksChanged() { callback_called_ = true; }

  NetworkManager::Stats MergeNetworkList(
      BasicNetworkManager& network_manager,
      std::vector<std::unique_ptr<Network>> list,
      bool* changed) {
    NetworkManager::Stats stats;
    network_manager.MergeNetworkList(std::move(list), changed, &stats);
    return stats;
  }

  bool IsIgnoredNetwork(BasicNetworkManager& network_manager,
                        const Network& network) {
    RTC_DCHECK_RUN_ON(network_manager.thread_);
    return network_manager.IsIgnoredNetwork(network);
  }

  IPAddress QueryDefaultLocalAddress(BasicNetworkManager& network_manager,
                                     int family) {
    RTC_DCHECK_RUN_ON(network_manager.thread_);
    return network_manager.QueryDefaultLocalAddress(family);
  }

  std::vector<std::unique_ptr<Network>> GetNetworks(
      const BasicNetworkManager& network_manager,
      bool include_ignored) {
    RTC_DCHECK_RUN_ON(network_manager.thread_);
    std::vector<std::unique_ptr<Network>> list;
    network_manager.CreateNetworks(include_ignored, &list);
    return list;
  }

  FakeNetworkMonitor* GetNetworkMonitor(BasicNetworkManager& network_manager) {
    RTC_DCHECK_RUN_ON(network_manager.thread_);
    return static_cast<FakeNetworkMonitor*>(
        network_manager.network_monitor_.get());
  }
  void ClearNetworks(BasicNetworkManager& network_manager) {
    network_manager.networks_.clear();
    network_manager.networks_map_.clear();
  }

  AdapterType GetAdapterType(BasicNetworkManager& network_manager) {
    std::vector<const Network*> list = network_manager.GetNetworks();
    RTC_CHECK_EQ(1, list.size());
    return list[0]->type();
  }

#if defined(WEBRTC_POSIX)
  // Separated from CreateNetworks for tests.
  static void CallConvertIfAddrs(
      const BasicNetworkManager& network_manager,
      struct ifaddrs* interfaces,
      bool include_ignored,
      std::vector<std::unique_ptr<Network>>* networks) {
    RTC_DCHECK_RUN_ON(network_manager.thread_);
    // Use the base IfAddrsConverter for test cases.
    std::unique_ptr<IfAddrsConverter> ifaddrs_converter(new IfAddrsConverter());
    network_manager.ConvertIfAddrs(interfaces, ifaddrs_converter.get(),
                                   include_ignored, networks);
  }

  struct sockaddr_in6* CreateIpv6Addr(absl::string_view ip_string,
                                      uint32_t scope_id) {
    struct sockaddr_in6* ipv6_addr =
        static_cast<struct sockaddr_in6*>(malloc(sizeof(struct sockaddr_in6)));
    memset(ipv6_addr, 0, sizeof(struct sockaddr_in6));
    ipv6_addr->sin6_family = AF_INET6;
    ipv6_addr->sin6_scope_id = scope_id;
    IPAddress ip;
    IPFromString(ip_string, &ip);
    ipv6_addr->sin6_addr = ip.ipv6_address();
    return ipv6_addr;
  }

  // Pointers created here need to be released via ReleaseIfAddrs.
  struct ifaddrs* AddIpv6Address(struct ifaddrs* list,
                                 char* if_name,
                                 absl::string_view ipv6_address,
                                 absl::string_view ipv6_netmask,
                                 uint32_t scope_id) {
    struct ifaddrs* if_addr = new struct ifaddrs;
    memset(if_addr, 0, sizeof(struct ifaddrs));
    if_addr->ifa_name = if_name;
    if_addr->ifa_addr = reinterpret_cast<struct sockaddr*>(
        CreateIpv6Addr(ipv6_address, scope_id));
    if_addr->ifa_netmask =
        reinterpret_cast<struct sockaddr*>(CreateIpv6Addr(ipv6_netmask, 0));
    if_addr->ifa_next = list;
    if_addr->ifa_flags = IFF_RUNNING;
    return if_addr;
  }

  struct ifaddrs* InstallIpv6Network(char* if_name,
                                     absl::string_view ipv6_address,
                                     absl::string_view ipv6_mask,
                                     BasicNetworkManager& network_manager) {
    ifaddrs* addr_list = nullptr;
    addr_list = AddIpv6Address(addr_list, if_name, ipv6_address, ipv6_mask, 0);
    std::vector<std::unique_ptr<Network>> result;
    bool changed;
    NetworkManager::Stats stats;
    CallConvertIfAddrs(network_manager, addr_list, true, &result);
    network_manager.MergeNetworkList(std::move(result), &changed, &stats);
    return addr_list;
  }

  struct sockaddr_in* CreateIpv4Addr(absl::string_view ip_string) {
    struct sockaddr_in* ipv4_addr =
        static_cast<struct sockaddr_in*>(malloc(sizeof(struct sockaddr_in)));
    memset(ipv4_addr, 0, sizeof(struct sockaddr_in));
    ipv4_addr->sin_family = AF_INET;
    IPAddress ip;
    IPFromString(ip_string, &ip);
    ipv4_addr->sin_addr = ip.ipv4_address();
    return ipv4_addr;
  }

  // Pointers created here need to be released via ReleaseIfAddrs.
  struct ifaddrs* AddIpv4Address(struct ifaddrs* list,
                                 char* if_name,
                                 absl::string_view ipv4_address,
                                 absl::string_view ipv4_netmask) {
    struct ifaddrs* if_addr = new struct ifaddrs;
    memset(if_addr, 0, sizeof(struct ifaddrs));
    if_addr->ifa_name = if_name;
    if_addr->ifa_addr =
        reinterpret_cast<struct sockaddr*>(CreateIpv4Addr(ipv4_address));
    if_addr->ifa_netmask =
        reinterpret_cast<struct sockaddr*>(CreateIpv4Addr(ipv4_netmask));
    if_addr->ifa_next = list;
    if_addr->ifa_flags = IFF_RUNNING;
    return if_addr;
  }

  struct ifaddrs* InstallIpv4Network(char* if_name,
                                     absl::string_view ipv4_address,
                                     absl::string_view ipv4_mask,
                                     BasicNetworkManager& network_manager) {
    ifaddrs* addr_list = nullptr;
    addr_list = AddIpv4Address(addr_list, if_name, ipv4_address, ipv4_mask);
    std::vector<std::unique_ptr<Network>> result;
    bool changed;
    NetworkManager::Stats stats;
    CallConvertIfAddrs(network_manager, addr_list, true, &result);
    network_manager.MergeNetworkList(std::move(result), &changed, &stats);
    return addr_list;
  }

  void ReleaseIfAddrs(struct ifaddrs* list) {
    struct ifaddrs* if_addr = list;
    while (if_addr != nullptr) {
      struct ifaddrs* next_addr = if_addr->ifa_next;
      free(if_addr->ifa_addr);
      free(if_addr->ifa_netmask);
      delete if_addr;
      if_addr = next_addr;
    }
  }
#endif  // defined(WEBRTC_POSIX)

 protected:
  const FieldTrials field_trials_ = CreateTestFieldTrials();
  const Environment env_ = CreateEnvironment(&field_trials_);
  AutoThread main_thread_;
  bool callback_called_ = false;
};

class TestBasicNetworkManager : public BasicNetworkManager {
 public:
  using BasicNetworkManager::BasicNetworkManager;
  using BasicNetworkManager::QueryDefaultLocalAddress;
  using BasicNetworkManager::set_default_local_addresses;
};

// Test that the Network ctor works properly.
TEST_F(NetworkTest, TestNetworkConstruct) {
  Network ipv4_network1("test_eth0", "Test Network Adapter 1",
                        IPAddress(0x12345600U), 24);
  EXPECT_EQ("test_eth0", ipv4_network1.name());
  EXPECT_EQ("Test Network Adapter 1", ipv4_network1.description());
  EXPECT_EQ(IPAddress(0x12345600U), ipv4_network1.prefix());
  EXPECT_EQ(24, ipv4_network1.prefix_length());
  EXPECT_EQ(AF_INET, ipv4_network1.family());
  EXPECT_FALSE(ipv4_network1.ignored());
}

TEST_F(NetworkTest, TestIsIgnoredNetworkIgnoresIPsStartingWith0) {
  Network ipv4_network1("test_eth0", "Test Network Adapter 1",
                        IPAddress(0x12345600U), 24, ADAPTER_TYPE_ETHERNET);
  Network ipv4_network2("test_eth1", "Test Network Adapter 2",
                        IPAddress(0x010000U), 24, ADAPTER_TYPE_ETHERNET);
  PhysicalSocketServer socket_server;
  BasicNetworkManager network_manager(env_, &socket_server);
  network_manager.StartUpdating();
  EXPECT_FALSE(IsIgnoredNetwork(network_manager, ipv4_network1));
  EXPECT_TRUE(IsIgnoredNetwork(network_manager, ipv4_network2));
}

// TODO(phoglund): Remove when ignore list goes away.
TEST_F(NetworkTest, TestIgnoreList) {
  Network ignore_me("ignore_me", "Ignore me please!", IPAddress(0x12345600U),
                    24);
  Network include_me("include_me", "Include me please!", IPAddress(0x12345600U),
                     24);
  PhysicalSocketServer socket_server;
  BasicNetworkManager default_network_manager(env_, &socket_server);
  default_network_manager.StartUpdating();
  EXPECT_FALSE(IsIgnoredNetwork(default_network_manager, ignore_me));
  EXPECT_FALSE(IsIgnoredNetwork(default_network_manager, include_me));

  BasicNetworkManager ignoring_network_manager(env_, &socket_server);
  std::vector<std::string> ignore_list;
  ignore_list.push_back("ignore_me");
  ignoring_network_manager.set_network_ignore_list(ignore_list);
  ignoring_network_manager.StartUpdating();
  EXPECT_TRUE(IsIgnoredNetwork(ignoring_network_manager, ignore_me));
  EXPECT_FALSE(IsIgnoredNetwork(ignoring_network_manager, include_me));
}

// Test is failing on Windows opt: b/11288214
TEST_F(NetworkTest, DISABLED_TestCreateNetworks) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  std::vector<std::unique_ptr<Network>> result = GetNetworks(manager, true);
  // We should be able to bind to any addresses we find.
  for (auto it = result.begin(); it != result.end(); ++it) {
    sockaddr_storage storage;
    memset(&storage, 0, sizeof(storage));
    IPAddress ip = (*it)->GetBestIP();
    SocketAddress bindaddress(ip, 0);
    bindaddress.SetScopeID((*it)->scope_id());
    // TODO(thaloun): Use Socket once it supports IPv6.
    int fd = static_cast<int>(socket(ip.family(), SOCK_STREAM, IPPROTO_TCP));
    if (fd > 0) {
      size_t ipsize = bindaddress.ToSockAddrStorage(&storage);
      EXPECT_GE(ipsize, 0U);
      int success = ::bind(fd, reinterpret_cast<sockaddr*>(&storage),
                           static_cast<int>(ipsize));
#if defined(WEBRTC_WIN)
      if (success)
        RTC_LOG_GLE(LS_ERROR) << "Socket bind failed.";
#endif
      EXPECT_EQ(0, success);
#if defined(WEBRTC_WIN)
      closesocket(fd);
#else
      close(fd);
#endif
    }
  }
}

// Test StartUpdating() and StopUpdating(). network_permission_state starts with
// ALLOWED.
TEST_F(NetworkTest, TestUpdateNetworks) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this] { OnNetworksChanged(); });
  EXPECT_EQ(NetworkManager::ENUMERATION_ALLOWED,
            manager.enumeration_permission());
  manager.StartUpdating();
  Thread::Current()->ProcessMessages(0);
  EXPECT_TRUE(callback_called_);
  callback_called_ = false;
  // Callback should be triggered immediately when StartUpdating
  // is called, after network update signal is already sent.
  manager.StartUpdating();
  EXPECT_TRUE(manager.started());
  Thread::Current()->ProcessMessages(0);
  EXPECT_TRUE(callback_called_);
  manager.StopUpdating();
  EXPECT_TRUE(manager.started());
  manager.StopUpdating();
  EXPECT_EQ(NetworkManager::ENUMERATION_ALLOWED,
            manager.enumeration_permission());
  EXPECT_FALSE(manager.started());
  manager.StopUpdating();
  EXPECT_FALSE(manager.started());
  callback_called_ = false;
  // Callback should be triggered immediately after StartUpdating is called
  // when start_count_ is reset to 0.
  manager.StartUpdating();
  Thread::Current()->ProcessMessages(0);
  EXPECT_TRUE(callback_called_);
}

// Verify that MergeNetworkList() merges network lists properly.
TEST_F(NetworkTest, TestBasicMergeNetworkList) {
  Network ipv4_network1("test_eth0", "Test Network Adapter 1",
                        IPAddress(0x12345600U), 24);
  Network ipv4_network2("test_eth1", "Test Network Adapter 2",
                        IPAddress(0x00010000U), 16);
  ipv4_network1.AddIP(IPAddress(0x12345678));
  ipv4_network2.AddIP(IPAddress(0x00010004));
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);

  // Add ipv4_network1 to the list of networks.
  std::vector<std::unique_ptr<Network>> list;
  list.push_back(ipv4_network1.Clone());
  bool changed;
  NetworkManager::Stats stats =
      MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  EXPECT_EQ(stats.ipv6_network_count, 0);
  EXPECT_EQ(stats.ipv4_network_count, 1);
  list.clear();  // It is fine to call .clear() on a moved-from vector.

  std::vector<const Network*> current = manager.GetNetworks();
  EXPECT_EQ(1U, current.size());
  EXPECT_TRUE(SameNameAndPrefix(ipv4_network1, *current[0]));
  const Network* net1 = current[0];
  uint16_t net_id1 = net1->id();
  EXPECT_EQ(1, net_id1);

  // Replace ipv4_network1 with ipv4_network2.
  list.push_back(ipv4_network2.Clone());
  stats = MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  EXPECT_EQ(stats.ipv6_network_count, 0);
  EXPECT_EQ(stats.ipv4_network_count, 1);
  list.clear();

  current = manager.GetNetworks();
  EXPECT_EQ(1U, current.size());
  EXPECT_TRUE(SameNameAndPrefix(ipv4_network2, *current[0]));
  const Network* net2 = current[0];
  uint16_t net_id2 = net2->id();
  // Network id will increase.
  EXPECT_LT(net_id1, net_id2);

  // Add Network2 back.
  list.push_back(ipv4_network1.Clone());
  list.push_back(ipv4_network2.Clone());
  stats = MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  EXPECT_EQ(stats.ipv6_network_count, 0);
  EXPECT_EQ(stats.ipv4_network_count, 2);
  list.clear();

  // Verify that we get previous instances of Network objects.
  current = manager.GetNetworks();
  EXPECT_EQ(2U, current.size());
  EXPECT_TRUE((net1 == current[0] && net2 == current[1]) ||
              (net1 == current[1] && net2 == current[0]));
  EXPECT_TRUE((net_id1 == current[0]->id() && net_id2 == current[1]->id()) ||
              (net_id1 == current[1]->id() && net_id2 == current[0]->id()));

  // Call MergeNetworkList() again and verify that we don't get update
  // notification.
  list.push_back(ipv4_network2.Clone());
  list.push_back(ipv4_network1.Clone());
  stats = MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_FALSE(changed);
  EXPECT_EQ(stats.ipv6_network_count, 0);
  EXPECT_EQ(stats.ipv4_network_count, 2);
  list.clear();

  // Verify that we get previous instances of Network objects.
  current = manager.GetNetworks();
  EXPECT_EQ(2U, current.size());
  EXPECT_TRUE((net1 == current[0] && net2 == current[1]) ||
              (net1 == current[1] && net2 == current[0]));
  EXPECT_TRUE((net_id1 == current[0]->id() && net_id2 == current[1]->id()) ||
              (net_id1 == current[1]->id() && net_id2 == current[0]->id()));
}

// Sets up some test IPv6 networks and appends them to list.
// Four networks are added - public and link local, for two interfaces.
void SetupNetworks(std::vector<std::unique_ptr<Network>>* list) {
  IPAddress ip;
  IPAddress prefix;
  EXPECT_TRUE(IPFromString("abcd::1234:5678:abcd:ef12", &ip));
  EXPECT_TRUE(IPFromString("abcd::", &prefix));
  // First, fake link-locals.
  Network ipv6_eth0_linklocalnetwork("test_eth0", "Test NetworkAdapter 1",
                                     prefix, 64);
  ipv6_eth0_linklocalnetwork.AddIP(ip);
  EXPECT_TRUE(IPFromString("abcd::5678:abcd:ef12:3456", &ip));
  Network ipv6_eth1_linklocalnetwork("test_eth1", "Test NetworkAdapter 2",
                                     prefix, 64);
  ipv6_eth1_linklocalnetwork.AddIP(ip);
  // Public networks:
  EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &ip));
  prefix = TruncateIP(ip, 64);
  Network ipv6_eth0_publicnetwork1_ip1("test_eth0", "Test NetworkAdapter 1",
                                       prefix, 64);
  ipv6_eth0_publicnetwork1_ip1.AddIP(ip);
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
  prefix = TruncateIP(ip, 64);
  Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 1",
                                       prefix, 64);
  ipv6_eth1_publicnetwork1_ip1.AddIP(ip);
  list->push_back(ipv6_eth0_linklocalnetwork.Clone());
  list->push_back(ipv6_eth1_linklocalnetwork.Clone());
  list->push_back(ipv6_eth0_publicnetwork1_ip1.Clone());
  list->push_back(ipv6_eth1_publicnetwork1_ip1.Clone());
}

// Test that the basic network merging case works.
TEST_F(NetworkTest, TestIPv6MergeNetworkList) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  std::vector<std::unique_ptr<Network>> networks;
  SetupNetworks(&networks);
  std::vector<const Network*> original_list = CopyNetworkPointers(networks);
  bool changed = false;
  NetworkManager::Stats stats =
      MergeNetworkList(manager, std::move(networks), &changed);
  EXPECT_TRUE(changed);
  EXPECT_EQ(stats.ipv6_network_count, 4);
  EXPECT_EQ(stats.ipv4_network_count, 0);
  std::vector<const Network*> list = manager.GetNetworks();
  // Verify that the original members are in the merged list.
  EXPECT_THAT(list, UnorderedElementsAreArray(original_list));
}

// Tests that when two network lists that describe the same set of networks are
// merged, that the changed callback is not called, and that the original
// objects remain in the result list.
TEST_F(NetworkTest, TestNoChangeMerge) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  std::vector<std::unique_ptr<Network>> networks;
  SetupNetworks(&networks);
  std::vector<const Network*> original_list = CopyNetworkPointers(networks);
  bool changed = false;
  MergeNetworkList(manager, std::move(networks), &changed);
  EXPECT_TRUE(changed);
  // Second list that describes the same networks but with new objects.
  std::vector<std::unique_ptr<Network>> second_networks;
  SetupNetworks(&second_networks);
  std::vector<const Network*> second_list =
      CopyNetworkPointers(second_networks);
  changed = false;
  MergeNetworkList(manager, std::move(second_networks), &changed);
  EXPECT_FALSE(changed);
  std::vector<const Network*> resulting_list = manager.GetNetworks();
  // Verify that the original members are in the merged list.
  EXPECT_THAT(resulting_list, UnorderedElementsAreArray(original_list));
  // Doublecheck that the new networks aren't in the list.
  for (const Network* network : second_list) {
    EXPECT_THAT(resulting_list, Not(Contains(network)));
  }
}

// Test that we can merge a network that is the same as another network but with
// a different IP. The original network should remain in the list, but have its
// IP changed.
TEST_F(NetworkTest, MergeWithChangedIP) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  std::vector<std::unique_ptr<Network>> original_list;
  SetupNetworks(&original_list);
  // Make a network that we're going to change.
  IPAddress ip;
  EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:faa:fee:faa", &ip));
  IPAddress prefix = TruncateIP(ip, 64);
  std::unique_ptr<Network> network_to_change = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", prefix, 64);
  std::unique_ptr<Network> changed_network = network_to_change->Clone();
  network_to_change->AddIP(ip);
  IPAddress changed_ip;
  EXPECT_TRUE(IPFromString("2401:fa01:4:1000:be30:f00:f00:f00", &changed_ip));
  changed_network->AddIP(changed_ip);
  const Network* const network_to_change_ptr = network_to_change.get();
  original_list.push_back(std::move(network_to_change));
  const size_t original_size = original_list.size();
  bool changed = false;
  MergeNetworkList(manager, std::move(original_list), &changed);
  std::vector<std::unique_ptr<Network>> second_list;
  SetupNetworks(&second_list);
  second_list.push_back(std::move(changed_network));
  changed = false;
  MergeNetworkList(manager, std::move(second_list), &changed);
  EXPECT_TRUE(changed);
  std::vector<const Network*> list = manager.GetNetworks();
  EXPECT_EQ(original_size, list.size());
  // Make sure the original network is still in the merged list.
  EXPECT_THAT(list, Contains(network_to_change_ptr));
  EXPECT_EQ(changed_ip, network_to_change_ptr->GetIPs().at(0));
}

TEST_F(NetworkTest, TestMultipleIPMergeNetworkList) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  std::vector<std::unique_ptr<Network>> original_list;
  SetupNetworks(&original_list);
  const Network* const network_ptr = original_list[2].get();
  bool changed = false;
  MergeNetworkList(manager, std::move(original_list), &changed);
  EXPECT_TRUE(changed);
  IPAddress ip;
  IPAddress check_ip;
  IPAddress prefix;
  // Add a second IP to the public network on eth0 (2401:fa00:4:1000/64).
  EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c6", &ip));
  prefix = TruncateIP(ip, 64);
  Network ipv6_eth0_publicnetwork1_ip2("test_eth0", "Test NetworkAdapter 1",
                                       prefix, 64);
  // This is the IP that already existed in the public network on eth0.
  EXPECT_TRUE(IPFromString("2401:fa00:4:1000:be30:5bff:fee5:c3", &check_ip));
  ipv6_eth0_publicnetwork1_ip2.AddIP(ip);

  std::vector<std::unique_ptr<Network>> second_list;
  SetupNetworks(&second_list);
  second_list.push_back(ipv6_eth0_publicnetwork1_ip2.Clone());
  changed = false;
  const auto network_copy = second_list[2]->Clone();
  MergeNetworkList(manager, std::move(second_list), &changed);
  EXPECT_TRUE(changed);
  // There should still be four networks.
  std::vector<const Network*> list = manager.GetNetworks();
  EXPECT_EQ(4U, list.size());
  // Check the gathered IPs.
  int matchcount = 0;
  for (const Network* network : list) {
    if (SameNameAndPrefix(*network, *network_copy)) {
      ++matchcount;
      EXPECT_EQ(1, matchcount);
      // This should be the same network object as before.
      EXPECT_EQ(network, network_ptr);
      // But with two addresses now.
      EXPECT_THAT(network->GetIPs(),
                  UnorderedElementsAre(InterfaceAddress(check_ip),
                                       InterfaceAddress(ip)));
    } else {
      // Check the IP didn't get added anywhere it wasn't supposed to.
      EXPECT_THAT(network->GetIPs(), Not(Contains(InterfaceAddress(ip))));
    }
  }
}

// Test that merge correctly distinguishes multiple networks on an interface.
TEST_F(NetworkTest, TestMultiplePublicNetworksOnOneInterfaceMerge) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  std::vector<std::unique_ptr<Network>> original_list;
  SetupNetworks(&original_list);
  bool changed = false;
  MergeNetworkList(manager, std::move(original_list), &changed);
  EXPECT_TRUE(changed);
  IPAddress ip;
  IPAddress prefix;
  // A second network for eth0.
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:5bff:fee5:c3", &ip));
  prefix = TruncateIP(ip, 64);
  Network ipv6_eth0_publicnetwork2_ip1("test_eth0", "Test NetworkAdapter 1",
                                       prefix, 64);
  ipv6_eth0_publicnetwork2_ip1.AddIP(ip);
  std::vector<std::unique_ptr<Network>> second_list;
  SetupNetworks(&second_list);
  second_list.push_back(ipv6_eth0_publicnetwork2_ip1.Clone());
  changed = false;
  MergeNetworkList(manager, std::move(second_list), &changed);
  EXPECT_TRUE(changed);
  // There should be five networks now.
  std::vector<const Network*> list = manager.GetNetworks();
  EXPECT_EQ(5U, list.size());
  // Check the resulting addresses.
  for (const Network* network : list) {
    if (network->prefix() == ipv6_eth0_publicnetwork2_ip1.prefix() &&
        network->name() == ipv6_eth0_publicnetwork2_ip1.name()) {
      // Check the new network has 1 IP and that it's the correct one.
      EXPECT_EQ(1U, network->GetIPs().size());
      EXPECT_EQ(ip, network->GetIPs().at(0));
    } else {
      // Check the IP didn't get added anywhere it wasn't supposed to.
      EXPECT_THAT(network->GetIPs(), Not(Contains(InterfaceAddress(ip))));
    }
  }
}

// Test that DumpNetworks does not crash.
TEST_F(NetworkTest, TestCreateAndDumpNetworks) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  std::vector<std::unique_ptr<Network>> list = GetNetworks(manager, true);
  bool changed;
  MergeNetworkList(manager, std::move(list), &changed);
  manager.DumpNetworks();
}

TEST_F(NetworkTest, TestIPv6Toggle) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  bool ipv6_found = false;
  for (const auto& network : GetNetworks(manager, true)) {
    if (network->prefix().family() == AF_INET6) {
      ipv6_found = true;
      break;
    }
  }
  EXPECT_TRUE(ipv6_found);
}

// Test that when network interfaces are sorted and given preference values,
// IPv6 comes first.
TEST_F(NetworkTest, IPv6NetworksPreferredOverIPv4) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  Network ipv4_network1("test_eth0", "Test Network Adapter 1",
                        IPAddress(0x12345600U), 24);
  ipv4_network1.AddIP(IPAddress(0x12345600U));

  IPAddress ip;
  IPAddress prefix;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:abcd:efab:cdef", &ip));
  prefix = TruncateIP(ip, 64);
  Network ipv6_eth1_publicnetwork1_ip1("test_eth1", "Test NetworkAdapter 2",
                                       prefix, 64);
  ipv6_eth1_publicnetwork1_ip1.AddIP(ip);

  std::vector<std::unique_ptr<Network>> list;
  list.push_back(ipv4_network1.Clone());
  list.push_back(ipv6_eth1_publicnetwork1_ip1.Clone());
  const Network* net1 = list[0].get();
  const Network* net2 = list[1].get();

  bool changed = false;
  MergeNetworkList(manager, std::move(list), &changed);
  ASSERT_TRUE(changed);
  // After sorting IPv6 network should be higher order than IPv4 networks.
  EXPECT_TRUE(net1->preference() < net2->preference());
}

// When two interfaces are equivalent in everything but name, they're expected
// to be preference-ordered by name. For example, "eth0" before "eth1".
TEST_F(NetworkTest, NetworksSortedByInterfaceName) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  auto eth0 = std::make_unique<Network>("test_eth0", "Test Network Adapter 1",
                                        IPAddress(0x65432100U), 24);
  eth0->AddIP(IPAddress(0x65432100U));
  auto eth1 = std::make_unique<Network>("test_eth1", "Test Network Adapter 2",
                                        IPAddress(0x12345600U), 24);
  eth1->AddIP(IPAddress(0x12345600U));
  std::vector<std::unique_ptr<Network>> list;
  const Network* eth0_ptr = eth0.get();
  const Network* eth1_ptr = eth1.get();
  // Add them to the list in the opposite of the expected sorted order, to
  // ensure sorting actually occurs.
  list.push_back(std::move(eth1));
  list.push_back(std::move(eth0));

  bool changed = false;
  MergeNetworkList(manager, std::move(list), &changed);
  ASSERT_TRUE(changed);
  // "test_eth0" should be preferred over "test_eth1".
  EXPECT_TRUE(eth0_ptr->preference() > eth1_ptr->preference());
}

TEST_F(NetworkTest, TestNetworkAdapterTypes) {
  Network wifi("wlan0", "Wireless Adapter", IPAddress(0x12345600U), 24,
               ADAPTER_TYPE_WIFI);
  EXPECT_EQ(ADAPTER_TYPE_WIFI, wifi.type());
  Network ethernet("eth0", "Ethernet", IPAddress(0x12345600U), 24,
                   ADAPTER_TYPE_ETHERNET);
  EXPECT_EQ(ADAPTER_TYPE_ETHERNET, ethernet.type());
  Network cellular("test_cell", "Cellular Adapter", IPAddress(0x12345600U), 24,
                   ADAPTER_TYPE_CELLULAR);
  EXPECT_EQ(ADAPTER_TYPE_CELLULAR, cellular.type());
  Network vpn("bridge_test", "VPN Adapter", IPAddress(0x12345600U), 24,
              ADAPTER_TYPE_VPN);
  EXPECT_EQ(ADAPTER_TYPE_VPN, vpn.type());
  Network unknown("test", "Test Adapter", IPAddress(0x12345600U), 24,
                  ADAPTER_TYPE_UNKNOWN);
  EXPECT_EQ(ADAPTER_TYPE_UNKNOWN, unknown.type());
}

#if defined(WEBRTC_POSIX)
// Verify that we correctly handle interfaces with no address.
TEST_F(NetworkTest, TestConvertIfAddrsNoAddress) {
  ifaddrs list;
  memset(&list, 0, sizeof(list));
  list.ifa_name = const_cast<char*>("test_iface");

  std::vector<std::unique_ptr<Network>> result;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, &list, true, &result);
  EXPECT_TRUE(result.empty());
}

// Verify that if there are two addresses on one interface, only one network
// is generated.
TEST_F(NetworkTest, TestConvertIfAddrsMultiAddressesOnOneInterface) {
  char if_name[20] = "rmnet0";
  ifaddrs* list = nullptr;
  list = AddIpv6Address(list, if_name, "1000:2000:3000:4000:0:0:0:1",
                        "FFFF:FFFF:FFFF:FFFF::", 0);
  list = AddIpv6Address(list, if_name, "1000:2000:3000:4000:0:0:0:2",
                        "FFFF:FFFF:FFFF:FFFF::", 0);
  std::vector<std::unique_ptr<Network>> result;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, list, true, &result);
  EXPECT_EQ(1U, result.size());
  bool changed;
  // This ensures we release the objects created in CallConvertIfAddrs.
  MergeNetworkList(manager, std::move(result), &changed);
  ReleaseIfAddrs(list);
}

TEST_F(NetworkTest, TestConvertIfAddrsNotRunning) {
  ifaddrs list;
  memset(&list, 0, sizeof(list));
  list.ifa_name = const_cast<char*>("test_iface");
  sockaddr ifa_addr;
  ifa_addr.sa_family = AF_UNSPEC;
  sockaddr ifa_netmask;
  list.ifa_addr = &ifa_addr;
  list.ifa_netmask = &ifa_netmask;

  std::vector<std::unique_ptr<Network>> result;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, &list, true, &result);
  EXPECT_TRUE(result.empty());
}

TEST_F(NetworkTest, TestConvertIfAddrsGetsNullAddr) {
  ifaddrs list;
  memset(&list, 0, sizeof(list));
  list.ifa_name = const_cast<char*>("test_iface");
  list.ifa_addr = nullptr;
  list.ifa_netmask = nullptr;

  std::vector<std::unique_ptr<Network>> result;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, &list, true, &result);
  EXPECT_TRUE(result.empty());
}

// Tests that the network type can be determined from the network monitor when
// it would otherwise be unknown.
TEST_F(NetworkTest, TestGetAdapterTypeFromNetworkMonitor) {
  char if_name[20] = "wifi0";
  std::string ipv6_address = "1000:2000:3000:4000:0:0:0:1";
  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF::";
  const Environment env = env_;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager_without_monitor(
      env, &socket_server, /*network_monitor_factory=*/nullptr);
  manager_without_monitor.StartUpdating();
  // A network created without a network monitor will get UNKNOWN type.
  ifaddrs* addr_list = InstallIpv6Network(if_name, ipv6_address, ipv6_mask,
                                          manager_without_monitor);
  EXPECT_EQ(ADAPTER_TYPE_UNKNOWN, GetAdapterType(manager_without_monitor));
  ReleaseIfAddrs(addr_list);

  // With the fake network monitor the type should be correctly determined.
  FakeNetworkMonitorFactory factory;
  BasicNetworkManager manager_with_monitor(env, &socket_server, &factory);
  manager_with_monitor.StartUpdating();
  // Add the same ipv6 address as before but it has the right network type
  // detected by the network monitor now.
  addr_list = InstallIpv6Network(if_name, ipv6_address, ipv6_mask,
                                 manager_with_monitor);
  EXPECT_EQ(ADAPTER_TYPE_WIFI, GetAdapterType(manager_with_monitor));
  ReleaseIfAddrs(addr_list);
}

// Test that the network type can be determined based on name matching in
// a few cases. Note that UNKNOWN type for non-matching strings has been tested
// in the above test.
TEST_F(NetworkTest, TestGetAdapterTypeFromNameMatching) {
  std::string ipv4_address1 = "192.0.0.121";
  std::string ipv4_mask = "255.255.255.0";
  std::string ipv6_address1 = "1000:2000:3000:4000:0:0:0:1";
  std::string ipv6_address2 = "1000:2000:3000:8000:0:0:0:1";
  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF::";
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();

  // IPSec interface; name is in form "ipsec<index>".
  char if_name[20] = "ipsec11";
  ifaddrs* addr_list =
      InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_VPN, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "lo0");
  addr_list = InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_LOOPBACK, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "eth0");
  addr_list = InstallIpv4Network(if_name, ipv4_address1, ipv4_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_ETHERNET, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "wlan0");
  addr_list = InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_WIFI, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

#if defined(WEBRTC_IOS)
  strcpy(if_name, "pdp_ip0");
  addr_list = InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_CELLULAR, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "en0");
  addr_list = InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_WIFI, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

#elif defined(WEBRTC_ANDROID)
  strcpy(if_name, "rmnet0");
  addr_list = InstallIpv6Network(if_name, ipv6_address1, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_CELLULAR, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "v4-rmnet_data0");
  addr_list = InstallIpv6Network(if_name, ipv6_address2, ipv6_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_CELLULAR, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);

  strcpy(if_name, "clat4");
  addr_list = InstallIpv4Network(if_name, ipv4_address1, ipv4_mask, manager);
  EXPECT_EQ(ADAPTER_TYPE_CELLULAR, GetAdapterType(manager));
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);
#endif
}

// Test that an adapter won't be included in the network list if there's a
// network monitor that says it's unavailable.
TEST_F(NetworkTest, TestNetworkMonitorIsAdapterAvailable) {
  char if_name1[20] = "pdp_ip0";
  char if_name2[20] = "pdp_ip1";
  ifaddrs* list = nullptr;
  list = AddIpv6Address(list, if_name1, "1000:2000:3000:4000:0:0:0:1",
                        "FFFF:FFFF:FFFF:FFFF::", 0);
  list = AddIpv6Address(list, if_name2, "1000:2000:3000:4000:0:0:0:2",
                        "FFFF:FFFF:FFFF:FFFF::", 0);
  std::vector<std::unique_ptr<Network>> result;

  // Sanity check that both interfaces are included by default.
  FakeNetworkMonitorFactory factory;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server, &factory);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, list, /*include_ignored=*/false, &result);
  EXPECT_EQ(2u, result.size());
  bool changed;
  // This ensures we release the objects created in CallConvertIfAddrs.
  MergeNetworkList(manager, std::move(result), &changed);
  result.clear();

  // Now simulate one interface being unavailable.
  FakeNetworkMonitor* network_monitor = GetNetworkMonitor(manager);
  network_monitor->set_unavailable_adapters({if_name1});
  CallConvertIfAddrs(manager, list, /*include_ignored=*/false, &result);
  EXPECT_EQ(1u, result.size());
  EXPECT_EQ(if_name2, result[0]->name());

  MergeNetworkList(manager, std::move(result), &changed);
  ReleaseIfAddrs(list);
}

#endif  // defined(WEBRTC_POSIX)

// Test MergeNetworkList successfully combines all IPs for the same
// prefix/length into a single Network.
TEST_F(NetworkTest, TestMergeNetworkList) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  std::vector<std::unique_ptr<Network>> list;

  // Create 2 IPAddress classes with only last digit different.
  IPAddress ip1, ip2;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:2", &ip2));

  // Create 2 networks with the same prefix and length.
  auto net1 = std::make_unique<Network>("em1", "em1", TruncateIP(ip1, 64), 64);
  auto net2 = std::make_unique<Network>("em1", "em1", TruncateIP(ip1, 64), 64);

  // Add different IP into each.
  net1->AddIP(ip1);
  net2->AddIP(ip2);

  list.push_back(std::move(net1));
  list.push_back(std::move(net2));
  bool changed;
  MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);

  std::vector<const Network*> list2 = manager.GetNetworks();

  // Make sure the resulted networklist has only 1 element and 2
  // IPAddresses.
  EXPECT_EQ(list2.size(), 1uL);
  EXPECT_EQ(list2[0]->GetIPs().size(), 2uL);
  EXPECT_THAT(list2[0]->GetIPs(), UnorderedElementsAre(InterfaceAddress(ip1),
                                                       InterfaceAddress(ip2)));
}

// Test that MergeNetworkList successfully detects the change if
// a network becomes inactive and then active again.
TEST_F(NetworkTest, TestMergeNetworkListWithInactiveNetworks) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  Network network1("test_wifi", "Test Network Adapter 1",
                   IPAddress(0x12345600U), 24);
  Network network2("test_eth0", "Test Network Adapter 2",
                   IPAddress(0x00010000U), 16);
  network1.AddIP(IPAddress(0x12345678));
  network2.AddIP(IPAddress(0x00010004));
  std::vector<std::unique_ptr<Network>> list;
  auto net1 = network1.Clone();
  const Network* const net1_ptr = net1.get();
  list.push_back(std::move(net1));
  bool changed;
  MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  list.clear();

  std::vector<const Network*> current = manager.GetNetworks();
  ASSERT_EQ(1U, current.size());
  EXPECT_EQ(net1_ptr, current[0]);

  list.clear();
  auto net2 = network2.Clone();
  const Network* const net2_ptr = net2.get();
  list.push_back(std::move(net2));
  MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  list.clear();

  current = manager.GetNetworks();
  ASSERT_EQ(1U, current.size());
  EXPECT_EQ(net2_ptr, current[0]);
  // Now network1 is inactive. Try to merge it again.
  list.clear();
  list.push_back(network1.Clone());
  MergeNetworkList(manager, std::move(list), &changed);
  EXPECT_TRUE(changed);
  list.clear();
  current = manager.GetNetworks();
  ASSERT_EQ(1U, current.size());
  EXPECT_TRUE(current[0]->active());
  EXPECT_EQ(net1_ptr, current[0]);
}

// Test that the filtering logic follows the defined ruleset in network.h.
TEST_F(NetworkTest, TestIPv6Selection) {
  InterfaceAddress ip;
  std::string ipstr;

  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c3";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_DEPRECATED, &ip));

  // Create a network with this prefix.
  Network ipv6_network("test_eth0", "Test NetworkAdapter", TruncateIP(ip, 64),
                       64);
  EXPECT_EQ(AF_INET6, ipv6_network.family());

  // When there is no address added, it should return an unspecified
  // address.
  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
  EXPECT_TRUE(IPIsUnspec(ipv6_network.GetBestIP()));

  // Deprecated one should not be returned.
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());

  // Add ULA one. ULA is unique local address which is starting either
  // with 0xfc or 0xfd.
  ipstr = "fd00:fa00:4:1000:be30:5bff:fee5:c4";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add global one.
  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c5";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add global dynamic temporary one.
  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c6";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_TEMPORARY, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
}

// Test that the filtering logic follows the defined ruleset in network.h.
TEST_F(NetworkTest, TestGetBestIPWithPreferGlobalIPv6ToLinkLocalEnabled) {
  InterfaceAddress ip, link_local;
  std::string ipstr;

  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c3";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_DEPRECATED, &ip));

  // Create a network with this prefix.
  Network ipv6_network("test_eth0", "Test NetworkAdapter", TruncateIP(ip, 64),
                       64, ADAPTER_TYPE_UNKNOWN);

  // When there is no address added, it should return an unspecified
  // address.
  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());
  EXPECT_TRUE(IPIsUnspec(ipv6_network.GetBestIP()));

  // Deprecated one should not be returned.
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), IPAddress());

  // Add ULA one. ULA is unique local address which is starting either
  // with 0xfc or 0xfd.
  ipstr = "fd00:fa00:4:1000:be30:5bff:fee5:c4";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add link local one.
  ipstr = "fe80::aabb:ccff:fedd:eeff";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
  ipv6_network.AddIP(link_local);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(link_local));

  // Add global one.
  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c5";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add another link local address, then the compatible address is still global
  // one.
  ipstr = "fe80::aabb:ccff:fedd:eedd";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
  ipv6_network.AddIP(link_local);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add global dynamic temporary one.
  ipstr = "2401:fa00:4:1000:be30:5bff:fee5:c6";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_TEMPORARY, &ip));
  ipv6_network.AddIP(ip);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));

  // Add another link local address, then the compatible address is still global
  // dynamic one.
  ipstr = "fe80::aabb:ccff:fedd:eedd";
  ASSERT_TRUE(IPFromString(ipstr, IPV6_ADDRESS_FLAG_NONE, &link_local));
  ipv6_network.AddIP(link_local);
  EXPECT_EQ(ipv6_network.GetBestIP(), static_cast<IPAddress>(ip));
}

TEST_F(NetworkTest, TestNetworkMonitoring) {
  FakeNetworkMonitorFactory factory;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server, &factory);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  manager.StartUpdating();
  FakeNetworkMonitor* network_monitor = GetNetworkMonitor(manager);
  EXPECT_TRUE(network_monitor && network_monitor->started());
  EXPECT_THAT(WaitUntil([&] { return callback_called_; }, IsTrue()), IsRtcOk());
  callback_called_ = false;

  // Clear the networks so that there will be network changes below.
  ClearNetworks(manager);
  // Network manager is started, so the callback is called when the network
  // monitor fires the network-change event.
  network_monitor->InovkeNetworksChangedCallbackForTesting();
  EXPECT_THAT(WaitUntil([&] { return callback_called_; }, IsTrue()), IsRtcOk());

  // Network manager is stopped.
  manager.StopUpdating();
  EXPECT_FALSE(GetNetworkMonitor(manager)->started());
}

// Fails on Android: https://bugs.chromium.org/p/webrtc/issues/detail?id=4364.
#if defined(WEBRTC_ANDROID)
#define MAYBE_DefaultLocalAddress DISABLED_DefaultLocalAddress
#else
#define MAYBE_DefaultLocalAddress DefaultLocalAddress
#endif
TEST_F(NetworkTest, MAYBE_DefaultLocalAddress) {
  MAYBE_SKIP_IPV4;
  IPAddress ip;
  FakeNetworkMonitorFactory factory;
  PhysicalSocketServer socket_server;
  TestBasicNetworkManager manager(env_, &socket_server, &factory);
  manager.SubscribeNetworksChanged(this, [this]() { OnNetworksChanged(); });
  manager.StartUpdating();
  EXPECT_THAT(WaitUntil([&] { return callback_called_; }, IsTrue()), IsRtcOk());

  // Make sure we can query default local address when an address for such
  // address family exists.
  std::vector<const Network*> networks = manager.GetNetworks();
  EXPECT_TRUE(!networks.empty());
  for (const Network* network : networks) {
    if (network->GetBestIP().family() == AF_INET) {
      EXPECT_TRUE(QueryDefaultLocalAddress(manager, AF_INET) != IPAddress());
    } else if (network->GetBestIP().family() == AF_INET6 &&
               !IPIsLoopback(network->GetBestIP())) {
      // Existence of an IPv6 loopback address doesn't mean it has IPv6 network
      // enabled.
      EXPECT_TRUE(QueryDefaultLocalAddress(manager, AF_INET6) != IPAddress());
    }
  }

  // GetDefaultLocalAddress should return the valid default address after set.
  manager.set_default_local_addresses(GetLoopbackIP(AF_INET),
                                      GetLoopbackIP(AF_INET6));
  EXPECT_TRUE(manager.GetDefaultLocalAddress(AF_INET, &ip));
  EXPECT_EQ(ip, GetLoopbackIP(AF_INET));
  EXPECT_TRUE(manager.GetDefaultLocalAddress(AF_INET6, &ip));
  EXPECT_EQ(ip, GetLoopbackIP(AF_INET6));

  // More tests on GetDefaultLocalAddress with ipv6 addresses where the set
  // default address may be different from the best IP address of any network.
  InterfaceAddress ip1;
  EXPECT_TRUE(IPFromString("abcd::1234:5678:abcd:1111",
                           IPV6_ADDRESS_FLAG_TEMPORARY, &ip1));
  // Create a network with a prefix of ip1.
  Network ipv6_network("test_eth0", "Test NetworkAdapter", TruncateIP(ip1, 64),
                       64);
  IPAddress ip2;
  EXPECT_TRUE(IPFromString("abcd::1234:5678:abcd:2222", &ip2));
  ipv6_network.AddIP(ip1);
  ipv6_network.AddIP(ip2);
  std::vector<std::unique_ptr<Network>> list;
  list.push_back(ipv6_network.Clone());
  bool changed;
  MergeNetworkList(manager, std::move(list), &changed);
  // If the set default address is not in any network, GetDefaultLocalAddress
  // should return it.
  IPAddress ip3;
  EXPECT_TRUE(IPFromString("abcd::1234:5678:abcd:3333", &ip3));
  manager.set_default_local_addresses(GetLoopbackIP(AF_INET), ip3);
  EXPECT_TRUE(manager.GetDefaultLocalAddress(AF_INET6, &ip));
  EXPECT_EQ(ip3, ip);
  // If the set default address is in a network, GetDefaultLocalAddress will
  // return the best IP in that network.
  manager.set_default_local_addresses(GetLoopbackIP(AF_INET), ip2);
  EXPECT_TRUE(manager.GetDefaultLocalAddress(AF_INET6, &ip));
  EXPECT_EQ(static_cast<IPAddress>(ip1), ip);

  manager.StopUpdating();
}

// Test that MergeNetworkList does not set change = true
// when changing from cellular_X to cellular_Y.
TEST_F(NetworkTest, TestWhenNetworkListChangeReturnsChangedFlag) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));
  auto net1 = std::make_unique<Network>("em1", "em1", TruncateIP(ip1, 64), 64);
  net1->set_type(ADAPTER_TYPE_CELLULAR_3G);
  net1->AddIP(ip1);
  std::vector<std::unique_ptr<Network>> list;
  list.push_back(std::move(net1));

  {
    bool changed;
    MergeNetworkList(manager, std::move(list), &changed);
    EXPECT_TRUE(changed);
    std::vector<const Network*> list2 = manager.GetNetworks();
    EXPECT_EQ(list2.size(), 1uL);
    EXPECT_EQ(ADAPTER_TYPE_CELLULAR_3G, list2[0]->type());
  }

  // Modify net1 from 3G to 4G
  {
    auto net2 =
        std::make_unique<Network>("em1", "em1", TruncateIP(ip1, 64), 64);
    net2->set_type(ADAPTER_TYPE_CELLULAR_4G);
    net2->AddIP(ip1);
    list.clear();
    list.push_back(std::move(net2));
    bool changed;
    MergeNetworkList(manager, std::move(list), &changed);

    // Change from 3G to 4G shall not trigger OnNetworksChanged,
    // i.e changed = false.
    EXPECT_FALSE(changed);
    std::vector<const Network*> list2 = manager.GetNetworks();
    ASSERT_EQ(list2.size(), 1uL);
    EXPECT_EQ(ADAPTER_TYPE_CELLULAR_4G, list2[0]->type());
  }

  // Don't modify.
  {
    auto net2 =
        std::make_unique<Network>("em1", "em1", TruncateIP(ip1, 64), 64);
    net2->set_type(ADAPTER_TYPE_CELLULAR_4G);
    net2->AddIP(ip1);
    list.clear();
    list.push_back(std::move(net2));
    bool changed;
    MergeNetworkList(manager, std::move(list), &changed);

    // No change.
    EXPECT_FALSE(changed);
    std::vector<const Network*> list2 = manager.GetNetworks();
    ASSERT_EQ(list2.size(), 1uL);
    EXPECT_EQ(ADAPTER_TYPE_CELLULAR_4G, list2[0]->type());
  }
}

#if defined(WEBRTC_POSIX)
TEST_F(NetworkTest, IgnoresMACBasedIPv6Address) {
  std::string ipv6_address = "2607:fc20:f340:1dc8:214:22ff:fe01:2345";
  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.StartUpdating();

  // IPSec interface; name is in form "ipsec<index>".
  char if_name[20] = "ipsec11";
  ifaddrs* addr_list =
      InstallIpv6Network(if_name, ipv6_address, ipv6_mask, manager);

  std::vector<const Network*> list = manager.GetNetworks();
  EXPECT_EQ(list.size(), 0u);
  ReleaseIfAddrs(addr_list);
}

TEST_F(NetworkTest, WebRTC_AllowMACBasedIPv6Address) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-AllowMACBasedIPv6/Enabled/");
  std::string ipv6_address = "2607:fc20:f340:1dc8:214:22ff:fe01:2345";
  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(CreateEnvironment(&field_trials), &socket_server);
  manager.StartUpdating();

  // IPSec interface; name is in form "ipsec<index>".
  char if_name[20] = "ipsec11";
  ifaddrs* addr_list =
      InstallIpv6Network(if_name, ipv6_address, ipv6_mask, manager);

  std::vector<const Network*> list = manager.GetNetworks();
  EXPECT_EQ(list.size(), 1u);
  ReleaseIfAddrs(addr_list);
}
#endif

#if defined(WEBRTC_POSIX)
TEST_F(NetworkTest, WebRTC_BindUsingInterfaceName) {
  char if_name1[20] = "wlan0";
  char if_name2[20] = "v4-wlan0";
  ifaddrs* list = nullptr;
  list = AddIpv6Address(list, if_name1, "1000:2000:3000:4000:0:0:0:1",
                        "FFFF:FFFF:FFFF:FFFF::", 0);
  list = AddIpv4Address(list, if_name2, "192.168.0.2", "255.255.255.255");
  std::vector<std::unique_ptr<Network>> result;

  // Sanity check that both interfaces are included by default.
  FakeNetworkMonitorFactory factory;
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server, &factory);
  manager.StartUpdating();
  CallConvertIfAddrs(manager, list, /*include_ignored=*/false, &result);
  EXPECT_EQ(2u, result.size());
  ReleaseIfAddrs(list);
  bool changed;
  // This ensures we release the objects created in CallConvertIfAddrs.
  MergeNetworkList(manager, std::move(result), &changed);
  result.clear();

  FakeNetworkMonitor* network_monitor = GetNetworkMonitor(manager);

  IPAddress ipv6;
  EXPECT_TRUE(IPFromString("1000:2000:3000:4000:0:0:0:1", &ipv6));
  IPAddress ipv4;
  EXPECT_TRUE(IPFromString("192.168.0.2", &ipv4));

  // The network monitor only knwos about the ipv6 address, interface.
  network_monitor->set_adapters({"wlan0"});
  network_monitor->set_ip_addresses({ipv6});
  EXPECT_EQ(manager.BindSocketToNetwork(/* fd */ 77, ipv6),
            NetworkBindingResult::SUCCESS);

  // But it will bind anyway using string matching...
  EXPECT_EQ(manager.BindSocketToNetwork(/* fd */ 77, ipv4),
            NetworkBindingResult::SUCCESS);
}
#endif

TEST_F(NetworkTest, NetworkCostVpn_Default) {
  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));
  FieldTrials field_trials = CreateTestFieldTrials();

  Network* net1 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
  net1->set_type(ADAPTER_TYPE_VPN);
  net1->set_underlying_type_for_vpn(ADAPTER_TYPE_ETHERNET);

  Network* net2 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
  net2->set_type(ADAPTER_TYPE_ETHERNET);

  EXPECT_EQ(net1->GetCost(field_trials), net2->GetCost(field_trials));
  delete net1;
  delete net2;
}

TEST_F(NetworkTest, NetworkCostVpn_VpnMoreExpensive) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-AddNetworkCostToVpn/Enabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  Network* net1 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
  net1->set_type(ADAPTER_TYPE_VPN);
  net1->set_underlying_type_for_vpn(ADAPTER_TYPE_ETHERNET);

  Network* net2 = new Network("em1", "em1", TruncateIP(ip1, 64), 64);
  net2->set_type(ADAPTER_TYPE_ETHERNET);

  EXPECT_GT(net1->GetCost(field_trials), net2->GetCost(field_trials));
  delete net1;
  delete net2;
}

class NetworkTestWithDifferentiatedCellular
    : public NetworkTest,
      public testing::WithParamInterface<std::string> {
 protected:
  FieldTrials CreateFieldTrials(absl::string_view s = "") {
    return CreateTestFieldTrials(absl::StrCat(
        "WebRTC-UseDifferentiatedCellularCosts/", GetParam(), "/", s));
  }
};

INSTANTIATE_TEST_SUITE_P(NetworkTestWithDifferentiatedCellular,
                         NetworkTestWithDifferentiatedCellular,
                         testing::Values("Disabled", "Enabled"));

TEST_P(NetworkTestWithDifferentiatedCellular, NetworkCostSlice_Default) {
  FieldTrials field_trials = CreateFieldTrials();

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  Network net1("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);
  net1.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

  Network net2("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);

  EXPECT_EQ(net1.GetCost(field_trials), net2.GetCost(field_trials));
}

TEST_P(NetworkTestWithDifferentiatedCellular, NetworkCostSlice_Disabled) {
  FieldTrials field_trials =
      CreateFieldTrials("WebRTC-UnifiedCommunications/Disabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  Network net1("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);
  net1.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

  Network net2("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);

  EXPECT_EQ(net1.GetCost(field_trials), net2.GetCost(field_trials));
}

TEST_P(NetworkTestWithDifferentiatedCellular,
       NetworkCostSlice_SliceLessExpensive) {
  FieldTrials field_trials =
      CreateFieldTrials("WebRTC-UnifiedCommunications/Enabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  Network net1("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);
  net1.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

  Network net2("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64,
               ADAPTER_TYPE_CELLULAR_5G);

  EXPECT_LT(net1.GetCost(field_trials), net2.GetCost(field_trials));
}

TEST_F(NetworkTest, NetworkCostSlice_IgnoredWhenInapplicable) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-UnifiedCommunications/Enabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  Network net1("wlan", "wlan", TruncateIP(ip1, 64), 64, ADAPTER_TYPE_WIFI);
  net1.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

  Network net2("wlan", "wlan", TruncateIP(ip1, 64), 64, ADAPTER_TYPE_WIFI);

  EXPECT_EQ(net1.GetCost(field_trials), net2.GetCost(field_trials));
}

TEST_F(NetworkTest, GuessAdapterFromNetworkCost_Default) {
  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-UseDifferentiatedCellularCosts/Enabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  for (auto type : kAllAdapterTypes) {
    if (type == ADAPTER_TYPE_VPN)
      continue;
    Network net1("em1", "em1", TruncateIP(ip1, 64), 64);
    net1.set_type(type);

    auto [guess, vpn, network_slice] =
        Network::GuessAdapterFromNetworkCost(net1.GetCost(field_trials));

    EXPECT_FALSE(vpn);
    if (type == ADAPTER_TYPE_LOOPBACK) {
      EXPECT_EQ(guess, ADAPTER_TYPE_ETHERNET);
    } else {
      EXPECT_EQ(type, guess);
    }
    EXPECT_EQ(NetworkSlice::NO_SLICE, network_slice);
  }
}

TEST_F(NetworkTest, GuessAdapterFromNetworkCost_Vpn) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-AddNetworkCostToVpn/Enabled/"
      "WebRTC-UseDifferentiatedCellularCosts/Enabled/");

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  for (auto type : kAllAdapterTypes) {
    if (type == ADAPTER_TYPE_VPN)
      continue;
    Network net1("em1", "em1", TruncateIP(ip1, 64), 64);
    net1.set_type(ADAPTER_TYPE_VPN);
    net1.set_underlying_type_for_vpn(type);

    auto [guess, vpn, network_slice] =
        Network::GuessAdapterFromNetworkCost(net1.GetCost(field_trials));

    EXPECT_TRUE(vpn);
    if (type == ADAPTER_TYPE_LOOPBACK) {
      EXPECT_EQ(guess, ADAPTER_TYPE_ETHERNET);
    } else {
      EXPECT_EQ(type, guess);
    }
    EXPECT_EQ(NetworkSlice::NO_SLICE, network_slice);
  }
}

TEST_P(NetworkTestWithDifferentiatedCellular,
       GuessAdapterFromNetworkCost_Slice) {
  FieldTrials field_trials = CreateFieldTrials(
      "WebRTC-AddNetworkCostToVpn/Enabled/"
      "WebRTC-UnifiedCommunications/Enabled/");

  bool differentiated_cellular_enabled = GetParam() == "Enabled";

  IPAddress ip1;
  EXPECT_TRUE(IPFromString("2400:4030:1:2c00:be30:0:0:1", &ip1));

  constexpr AdapterType sliceable_cellular_types[] = {ADAPTER_TYPE_CELLULAR_5G,
                                                      ADAPTER_TYPE_CELLULAR};

  for (AdapterType actual_type : sliceable_cellular_types) {
    AdapterType expected_guess =
        differentiated_cellular_enabled ? actual_type : ADAPTER_TYPE_CELLULAR;

    {
      Network net1("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64);
      net1.set_type(actual_type);
      net1.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

      auto [guess, vpn, network_slice] =
          Network::GuessAdapterFromNetworkCost(net1.GetCost(field_trials));

      EXPECT_EQ(expected_guess, guess);
      EXPECT_FALSE(vpn);
      EXPECT_EQ(NetworkSlice::UNIFIED_COMMUNICATIONS, network_slice);
    }

    {
      Network net2("rmnet1", "rmnet1", TruncateIP(ip1, 64), 64);
      net2.set_type(ADAPTER_TYPE_VPN);
      net2.set_underlying_type_for_vpn(actual_type);
      net2.set_network_slice(NetworkSlice::UNIFIED_COMMUNICATIONS);

      auto [guess, vpn, network_slice] =
          Network::GuessAdapterFromNetworkCost(net2.GetCost(field_trials));

      EXPECT_EQ(expected_guess, guess);
      EXPECT_TRUE(vpn);
      EXPECT_EQ(NetworkSlice::UNIFIED_COMMUNICATIONS, network_slice);
    }
  }
}

TEST_F(NetworkTest, VpnList) {
  PhysicalSocketServer socket_server;
  {
    BasicNetworkManager manager(env_, &socket_server);
    manager.set_vpn_list({NetworkMask(IPFromString("192.168.0.0"), 16)});
    manager.StartUpdating();
    EXPECT_TRUE(manager.IsConfiguredVpn(IPFromString("192.168.1.1"), 32));
    EXPECT_TRUE(manager.IsConfiguredVpn(IPFromString("192.168.12.1"), 24));
    EXPECT_TRUE(manager.IsConfiguredVpn(IPFromString("192.168.0.0"), 16));
    EXPECT_TRUE(manager.IsConfiguredVpn(IPFromString("192.168.0.0"), 24));
    EXPECT_FALSE(manager.IsConfiguredVpn(IPFromString("192.133.1.1"), 32));
    EXPECT_FALSE(manager.IsConfiguredVpn(IPFromString("192.133.0.0"), 16));
    EXPECT_FALSE(manager.IsConfiguredVpn(IPFromString("192.168.0.0"), 15));
  }
  {
    BasicNetworkManager manager(env_, &socket_server);
    manager.set_vpn_list({NetworkMask(IPFromString("192.168.0.0"), 24)});
    manager.StartUpdating();
    EXPECT_FALSE(manager.IsConfiguredVpn(IPFromString("192.168.1.1"), 32));
    EXPECT_TRUE(manager.IsConfiguredVpn(IPFromString("192.168.0.1"), 32));
  }
}

#if defined(WEBRTC_POSIX)
// TODO(webrtc:13114): Implement the InstallIpv4Network for windows.
TEST_F(NetworkTest, VpnListOverrideAdapterType) {
  PhysicalSocketServer socket_server;
  BasicNetworkManager manager(env_, &socket_server);
  manager.set_vpn_list({NetworkMask(IPFromString("192.168.0.0"), 16)});
  manager.StartUpdating();

  char if_name[20] = "eth0";
  auto addr_list =
      InstallIpv4Network(if_name, "192.168.1.23", "255.255.255.255", manager);

  std::vector<const Network*> list = manager.GetNetworks();
  ASSERT_EQ(1u, list.size());
  EXPECT_EQ(ADAPTER_TYPE_VPN, list[0]->type());
  EXPECT_EQ(ADAPTER_TYPE_ETHERNET, list[0]->underlying_type_for_vpn());
  ClearNetworks(manager);
  ReleaseIfAddrs(addr_list);
}
#endif  // defined(WEBRTC_POSIX)

TEST_F(NetworkTest, HardcodedVpn) {
  const uint8_t cisco[] = {0x0, 0x5, 0x9A, 0x3C, 0x7A, 0x0};
  const uint8_t global[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x1};
  const uint8_t unknown[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x0};
  const uint8_t five_bytes[] = {0x2, 0x50, 0x41, 0x0, 0x0};
  EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(cisco));
  EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(global));

  EXPECT_FALSE(
      NetworkManagerBase::IsVpnMacAddress(ArrayView<const uint8_t>(cisco, 5)));
  EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(five_bytes));
  EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(unknown));
  EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress({}));
}

TEST(CompareNetworks, IrreflexivityTest) {
  // x < x is false
  auto network = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network, network));
}

TEST(CompareNetworks, AsymmetryTest) {
  // x < y and y < x cannot be both true
  auto network_a = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_b = std::make_unique<Network>(
      "test_eth1", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_a, network_b));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_b, network_a));

  auto network_c = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345500U), 24);
  auto network_d = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_c, network_d));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_d, network_c));
}

TEST(CompareNetworks, TransitivityTest) {
  // x < y and y < z imply x < z
  auto network_a = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_b = std::make_unique<Network>(
      "test_eth1", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_c = std::make_unique<Network>(
      "test_eth2", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_a, network_b));
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_b, network_c));

  auto network_d = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_e = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345700U), 24);
  auto network_f = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345800U), 24);
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_d, network_e));
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_e, network_f));
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_d, network_f));
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_a, network_c));
}

TEST(CompareNetworks, TransitivityOfIncomparabilityTest) {
  // x == y and y == z imply x == z,
  // where x == y means x < y and y < x are both false
  auto network_a = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 23);
  auto network_b = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_c = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345700U), 24);

  // network_a < network_b
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_a, network_b));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_b, network_a));

  // network_b < network_c
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_b, network_c));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_c, network_b));

  // network_a < network_c
  EXPECT_TRUE(webrtc_network_internal::CompareNetworks(network_a, network_c));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_c, network_a));

  auto network_d = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_e = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);
  auto network_f = std::make_unique<Network>(
      "test_eth0", "Test Network Adapter 1", IPAddress(0x12345600U), 24);

  // network_d == network_e
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_d, network_e));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_e, network_d));

  // network_e == network_f
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_e, network_f));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_f, network_e));

  // network_d == network_f
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_d, network_f));
  EXPECT_FALSE(webrtc_network_internal::CompareNetworks(network_f, network_d));
}

}  // namespace webrtc
