// Copyright 2019 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/socket/client_socket_pool.h"

#include <string>
#include <vector>

#include "base/test/scoped_feature_list.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/privacy_mode.h"
#include "net/base/schemeful_site.h"
#include "net/dns/public/secure_dns_policy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"

namespace net {

namespace {

TEST(ClientSocketPool, GroupIdOperators) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      features::kPartitionConnectionsByNetworkIsolationKey);

  // Each of these lists is in "<" order, as defined by Group::operator< on the
  // corresponding field.

  const uint16_t kPorts[] = {
      80,
      81,
      443,
  };

  const char* kSchemes[] = {
      url::kHttpScheme,
      url::kHttpsScheme,
  };

  const char* kHosts[] = {
      "a",
      "b",
      "c",
  };

  const PrivacyMode kPrivacyModes[] = {
      PrivacyMode::PRIVACY_MODE_DISABLED,
      PrivacyMode::PRIVACY_MODE_ENABLED,
  };

  const SchemefulSite kSiteA(GURL("http://a.test/"));
  const SchemefulSite kSiteB(GURL("http://b.test/"));
  const NetworkAnonymizationKey kNetworkAnonymizationKeys[] = {
      NetworkAnonymizationKey::CreateSameSite(kSiteA),
      NetworkAnonymizationKey::CreateSameSite(kSiteB),
  };

  const SecureDnsPolicy kDisableSecureDnsValues[] = {SecureDnsPolicy::kAllow,
                                                     SecureDnsPolicy::kDisable};

  // All previously created |group_ids|. They should all be less than the
  // current group under consideration.
  std::vector<ClientSocketPool::GroupId> group_ids;

  // Iterate through all sets of group ids, from least to greatest.
  for (const auto& port : kPorts) {
    SCOPED_TRACE(port);
    for (const char* scheme : kSchemes) {
      SCOPED_TRACE(scheme);
      for (const char* host : kHosts) {
        SCOPED_TRACE(host);
        for (const auto& privacy_mode : kPrivacyModes) {
          SCOPED_TRACE(privacy_mode);
          for (const auto& network_anonymization_key :
               kNetworkAnonymizationKeys) {
            SCOPED_TRACE(network_anonymization_key.ToDebugString());
            for (const auto& secure_dns_policy : kDisableSecureDnsValues) {
              ClientSocketPool::GroupId group_id(
                  url::SchemeHostPort(scheme, host, port), privacy_mode,
                  network_anonymization_key, secure_dns_policy);
              for (const auto& lower_group_id : group_ids) {
                EXPECT_FALSE(lower_group_id == group_id);
                EXPECT_TRUE(lower_group_id < group_id);
                EXPECT_FALSE(group_id < lower_group_id);
              }

              group_ids.push_back(group_id);

              // Compare |group_id| to itself. Use two different copies of
              // |group_id|'s value, since to protect against bugs where an
              // object only equals itself.
              EXPECT_TRUE(group_ids.back() == group_id);
              EXPECT_FALSE(group_ids.back() < group_id);
              EXPECT_FALSE(group_id < group_ids.back());
            }
          }
        }
      }
    }
  }
}

TEST(ClientSocketPool, GroupIdToString) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      features::kPartitionConnectionsByNetworkIsolationKey);

  EXPECT_EQ("http://foo <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpScheme, "foo", 80),
                PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());
  EXPECT_EQ("http://bar:443 <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpScheme, "bar", 443),
                PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());
  EXPECT_EQ("pm/http://bar <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpScheme, "bar", 80),
                PrivacyMode::PRIVACY_MODE_ENABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());

  EXPECT_EQ("https://foo:80 <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpsScheme, "foo", 80),
                PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());
  EXPECT_EQ("https://bar <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpsScheme, "bar", 443),
                PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());
  EXPECT_EQ("pm/https://bar:80 <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpsScheme, "bar", 80),
                PrivacyMode::PRIVACY_MODE_ENABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kAllow)
                .ToString());

  EXPECT_EQ("https://foo <https://foo.test cross_site>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpsScheme, "foo", 443),
                PrivacyMode::PRIVACY_MODE_DISABLED,
                NetworkAnonymizationKey::CreateCrossSite(
                    SchemefulSite(GURL("https://foo.test"))),
                SecureDnsPolicy::kAllow)
                .ToString());

  EXPECT_EQ("dsd/pm/https://bar:80 <null>",
            ClientSocketPool::GroupId(
                url::SchemeHostPort(url::kHttpsScheme, "bar", 80),
                PrivacyMode::PRIVACY_MODE_ENABLED, NetworkAnonymizationKey(),
                SecureDnsPolicy::kDisable)
                .ToString());
}

TEST(ClientSocketPool, PartitionConnectionsByNetworkIsolationKeyDisabled) {
  const SchemefulSite kSiteFoo(GURL("https://foo.com"));
  const SchemefulSite kSiteBar(GURL("https://bar.com"));
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(
      features::kPartitionConnectionsByNetworkIsolationKey);

  ClientSocketPool::GroupId group_id1(
      url::SchemeHostPort(url::kHttpsScheme, "foo", 443),
      PrivacyMode::PRIVACY_MODE_DISABLED,
      NetworkAnonymizationKey::CreateSameSite(kSiteFoo),
      SecureDnsPolicy::kAllow);

  ClientSocketPool::GroupId group_id2(
      url::SchemeHostPort(url::kHttpsScheme, "foo", 443),
      PrivacyMode::PRIVACY_MODE_DISABLED,
      NetworkAnonymizationKey::CreateSameSite(kSiteBar),
      SecureDnsPolicy::kAllow);

  EXPECT_FALSE(group_id1.network_anonymization_key().IsFullyPopulated());
  EXPECT_FALSE(group_id2.network_anonymization_key().IsFullyPopulated());
  EXPECT_EQ(group_id1.network_anonymization_key(),
            group_id2.network_anonymization_key());
  EXPECT_EQ(group_id1, group_id2);

  EXPECT_EQ("https://foo", group_id1.ToString());
  EXPECT_EQ("https://foo", group_id2.ToString());
}

}  // namespace

}  // namespace net
