// Copyright 2014 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 <stddef.h>

#include <map>
#include <string>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/mock_entropy_provider.h"
#include "build/build_config.h"
#include "chrome/browser/io_thread.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/policy/core/common/mock_policy_service.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h"
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/features/features.h"
#include "net/cert_net/nss_ocsp.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_network_session.h"
#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/quic/chromium/quic_stream_factory.h"
#include "net/quic/core/quic_tag.h"
#include "net/quic/core/quic_versions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/event_router_forwarder.h"
#endif

#if defined(OS_CHROMEOS)
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/network/network_handler.h"
#endif

namespace test {

using ::testing::ReturnRef;

// Class used for accessing IOThread methods (friend of IOThread).
class IOThreadPeer {
 public:
  static net::HttpAuthPreferences* GetAuthPreferences(IOThread* io_thread) {
    return io_thread->globals()->http_auth_preferences.get();
  }
  static void ConfigureParamsFromFieldTrialsAndCommandLine(
      const base::CommandLine& command_line,
      bool is_quic_allowed_by_policy,
      net::HttpNetworkSession::Params* params) {
    IOThread::ConfigureParamsFromFieldTrialsAndCommandLine(
        command_line, is_quic_allowed_by_policy, false, params);
  }
};

class IOThreadTestWithIOThreadObject : public testing::Test {
 public:
  // These functions need to be public, since it is difficult to bind to
  // protected functions in a test (the code would need to explicitly contain
  // the name of the actual test class).
  void CheckCnameLookup(bool expected) {
    auto* http_auth_preferences =
        IOThreadPeer::GetAuthPreferences(io_thread_.get());
    ASSERT_NE(nullptr, http_auth_preferences);
    EXPECT_EQ(expected, http_auth_preferences->NegotiateDisableCnameLookup());
  }

  void CheckNegotiateEnablePort(bool expected) {
    auto* http_auth_preferences =
        IOThreadPeer::GetAuthPreferences(io_thread_.get());
    ASSERT_NE(nullptr, http_auth_preferences);
    EXPECT_EQ(expected, http_auth_preferences->NegotiateEnablePort());
  }

  void CheckEffectiveConnectionType(net::EffectiveConnectionType expected) {
    ASSERT_EQ(expected,
              io_thread_->globals()
                  ->network_quality_estimator->GetEffectiveConnectionType());
  }

#if defined(OS_ANDROID)
  void CheckAuthAndroidNegoitateAccountType(std::string expected) {
    auto* http_auth_preferences =
        IOThreadPeer::GetAuthPreferences(io_thread_.get());
    ASSERT_NE(nullptr, http_auth_preferences);
    EXPECT_EQ(expected,
              http_auth_preferences->AuthAndroidNegotiateAccountType());
  }
#endif

  void CheckCanUseDefaultCredentials(bool expected, const GURL& url) {
    auto* http_auth_preferences =
        IOThreadPeer::GetAuthPreferences(io_thread_.get());
    EXPECT_EQ(expected, http_auth_preferences->CanUseDefaultCredentials(url));
  }

  void CheckCanDelegate(bool expected, const GURL& url) {
    auto* http_auth_preferences =
        IOThreadPeer::GetAuthPreferences(io_thread_.get());
    EXPECT_EQ(expected, http_auth_preferences->CanDelegate(url));
  }

 protected:
  IOThreadTestWithIOThreadObject()
      : thread_bundle_(
            content::TestBrowserThreadBundle::REAL_IO_THREAD |
            content::TestBrowserThreadBundle::DONT_CREATE_BROWSER_THREADS) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
    event_router_forwarder_ = new extensions::EventRouterForwarder;
#endif
    PrefRegistrySimple* pref_registry = pref_service_.registry();
    IOThread::RegisterPrefs(pref_registry);
    PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry);
    ssl_config::SSLConfigServiceManager::RegisterPrefs(pref_registry);

    // Set up default function behaviour.
    EXPECT_CALL(policy_service_,
                GetPolicies(policy::PolicyNamespace(
                    policy::POLICY_DOMAIN_CHROME, std::string())))
        .WillRepeatedly(ReturnRef(policy_map_));

#if defined(OS_CHROMEOS)
    // Needed by IOThread constructor.
    chromeos::DBusThreadManager::Initialize();
    chromeos::NetworkHandler::Initialize();
#endif
  }

  void CreateThreads() {
    // The IOThread constructor registers the IOThread object with as the
    // BrowserThreadDelegate for the io thread.
    io_thread_.reset(new IOThread(&pref_service_, &policy_service_, nullptr,
#if BUILDFLAG(ENABLE_EXTENSIONS)
                                  event_router_forwarder_.get()
#else
                                  nullptr
#endif
                                      ));
    // Now that IOThread object is registered starting the threads will
    // call the IOThread::Init(). This sets up the environment needed for
    // these tests.
    thread_bundle_.CreateBrowserThreads();
  }

  ~IOThreadTestWithIOThreadObject() override {
#if defined(USE_NSS_CERTS)
    // Reset OCSPIOLoop thread checks, so that the test runner can run
    // futher tests in the same process.
    RunOnIOThreadBlocking(base::Bind(&net::ResetNSSHttpIOForTesting));
#endif
#if defined(OS_CHROMEOS)
    chromeos::NetworkHandler::Shutdown();
    chromeos::DBusThreadManager::Shutdown();
#endif
  }

  TestingPrefServiceSimple* pref_service() { return &pref_service_; }

  void RunOnIOThreadBlocking(const base::Closure& task) {
    base::RunLoop run_loop;
    content::BrowserThread::PostTaskAndReply(
        content::BrowserThread::IO, FROM_HERE, task, run_loop.QuitClosure());
    run_loop.Run();
  }

 private:
  base::ShadowingAtExitManager at_exit_manager_;
  TestingPrefServiceSimple pref_service_;
#if BUILDFLAG(ENABLE_EXTENSIONS)
  scoped_refptr<extensions::EventRouterForwarder> event_router_forwarder_;
#endif
  policy::PolicyMap policy_map_;
  policy::MockPolicyService policy_service_;
  // The ordering of the declarations of |io_thread_object_| and
  // |thread_bundle_| matters. An IOThread cannot be deleted until all of
  // the globals have been reset to their initial state via CleanUp. As
  // TestBrowserThreadBundle's destructor is responsible for calling
  // CleanUp(), the IOThread must be declared before the bundle, so that
  // the bundle is deleted first.
  std::unique_ptr<IOThread> io_thread_;
  content::TestBrowserThreadBundle thread_bundle_;
};

TEST_F(IOThreadTestWithIOThreadObject, UpdateNegotiateDisableCnameLookup) {
  // This test uses the kDisableAuthNegotiateCnameLookup to check that
  // the HttpAuthPreferences are correctly initialized and running on the
  // IO thread. The other preferences are tested by the HttpAuthPreferences
  // unit tests.
  CreateThreads();
  pref_service()->SetBoolean(prefs::kDisableAuthNegotiateCnameLookup, false);
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCnameLookup,
                 base::Unretained(this), false));
  pref_service()->SetBoolean(prefs::kDisableAuthNegotiateCnameLookup, true);
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCnameLookup,
                 base::Unretained(this), true));
}

TEST_F(IOThreadTestWithIOThreadObject, UpdateEnableAuthNegotiatePort) {
  CreateThreads();
  pref_service()->SetBoolean(prefs::kEnableAuthNegotiatePort, false);
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckNegotiateEnablePort,
                 base::Unretained(this), false));
  pref_service()->SetBoolean(prefs::kEnableAuthNegotiatePort, true);
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckNegotiateEnablePort,
                 base::Unretained(this), true));
}

TEST_F(IOThreadTestWithIOThreadObject, UpdateServerWhitelist) {
  CreateThreads();
  GURL url("http://test.example.com");

  pref_service()->SetString(prefs::kAuthServerWhitelist, "xxx");
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCanUseDefaultCredentials,
                 base::Unretained(this), false, url));

  pref_service()->SetString(prefs::kAuthServerWhitelist, "*");
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCanUseDefaultCredentials,
                 base::Unretained(this), true, url));
}

TEST_F(IOThreadTestWithIOThreadObject, UpdateDelegateWhitelist) {
  CreateThreads();
  GURL url("http://test.example.com");

  pref_service()->SetString(prefs::kAuthNegotiateDelegateWhitelist, "");
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCanDelegate,
                 base::Unretained(this), false, url));

  pref_service()->SetString(prefs::kAuthNegotiateDelegateWhitelist, "*");
  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckCanDelegate,
                 base::Unretained(this), true, url));
}

#if defined(OS_ANDROID)
// AuthAndroidNegotiateAccountType is only used on Android.
TEST_F(IOThreadTestWithIOThreadObject, UpdateAuthAndroidNegotiateAccountType) {
  CreateThreads();
  pref_service()->SetString(prefs::kAuthAndroidNegotiateAccountType, "acc1");
  RunOnIOThreadBlocking(base::Bind(
      &IOThreadTestWithIOThreadObject::CheckAuthAndroidNegoitateAccountType,
      base::Unretained(this), "acc1"));
  pref_service()->SetString(prefs::kAuthAndroidNegotiateAccountType, "acc2");
  RunOnIOThreadBlocking(base::Bind(
      &IOThreadTestWithIOThreadObject::CheckAuthAndroidNegoitateAccountType,
      base::Unretained(this), "acc2"));
}
#endif

TEST_F(IOThreadTestWithIOThreadObject, ForceECTFromCommandLine) {
  CreateThreads();
  base::CommandLine::Init(0, nullptr);
  ASSERT_TRUE(base::CommandLine::InitializedForCurrentProcess());
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      "--force-effective-connection-type", "Slow-2G");

  RunOnIOThreadBlocking(base::Bind(
      &IOThreadTestWithIOThreadObject::CheckEffectiveConnectionType,
      base::Unretained(this), net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G));
}

TEST_F(IOThreadTestWithIOThreadObject, ForceECTUsingFieldTrial) {
  base::CommandLine::Init(0, nullptr);
  ASSERT_TRUE(base::CommandLine::InitializedForCurrentProcess());

  variations::testing::ClearAllVariationParams();
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "2G";
  ASSERT_TRUE(variations::AssociateVariationParams(
      "NetworkQualityEstimator", "Enabled", variation_params));

  base::FieldTrialList field_trial_list(nullptr);
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("NetworkQualityEstimator",
                                                     "Enabled"));

  // Create threads after the field trial has been set.
  CreateThreads();

  RunOnIOThreadBlocking(
      base::Bind(&IOThreadTestWithIOThreadObject::CheckEffectiveConnectionType,
                 base::Unretained(this), net::EFFECTIVE_CONNECTION_TYPE_2G));
}

TEST_F(IOThreadTestWithIOThreadObject, ECTFromCommandLineOverridesFieldTrial) {
  base::CommandLine::Init(0, nullptr);
  ASSERT_TRUE(base::CommandLine::InitializedForCurrentProcess());
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      "--force-effective-connection-type", "Slow-2G");

  variations::testing::ClearAllVariationParams();
  std::map<std::string, std::string> variation_params;
  variation_params["force_effective_connection_type"] = "2G";
  ASSERT_TRUE(variations::AssociateVariationParams(
      "NetworkQualityEstimator", "Enabled", variation_params));

  base::FieldTrialList field_trial_list(nullptr);
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("NetworkQualityEstimator",
                                                     "Enabled"));

  // Create threads after the field trial has been set.
  CreateThreads();
  RunOnIOThreadBlocking(base::Bind(
      &IOThreadTestWithIOThreadObject::CheckEffectiveConnectionType,
      base::Unretained(this), net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G));
}

class ConfigureParamsFromFieldTrialsAndCommandLineTest
    : public ::testing::Test {
 public:
  ConfigureParamsFromFieldTrialsAndCommandLineTest()
      : command_line_(base::CommandLine::NO_PROGRAM),
        is_quic_allowed_by_policy_(true) {}

 protected:
  void ConfigureParamsFromFieldTrialsAndCommandLine() {
    IOThreadPeer::ConfigureParamsFromFieldTrialsAndCommandLine(
        command_line_, is_quic_allowed_by_policy_, &params_);
  }

  base::CommandLine command_line_;
  bool is_quic_allowed_by_policy_;
  net::HttpNetworkSession::Params params_;
};

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest, Default) {
  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_TRUE(params_.enable_http2);
  EXPECT_FALSE(params_.enable_quic);
  EXPECT_EQ(1350u, params_.quic_max_packet_length);
  EXPECT_EQ(net::QuicTagVector(), params_.quic_connection_options);
  EXPECT_TRUE(params_.origins_to_force_quic_on.empty());
  EXPECT_FALSE(params_.enable_user_alternate_protocol_ports);
  EXPECT_FALSE(params_.ignore_certificate_errors);
  EXPECT_EQ(0, params_.testing_fixed_http_port);
  EXPECT_EQ(0, params_.testing_fixed_https_port);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       Http2CommandLineDisableHttp2) {
  command_line_.AppendSwitch("disable-http2");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_FALSE(params_.enable_http2);
}

// Command line flag should not only disable QUIC but should also prevent QUIC
// related field trials and command line flags from being parsed.
TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       DisableQuicFromCommandLineOverridesFieldTrial) {
  auto field_trial_list =
      base::MakeUnique<base::FieldTrialList>(
          base::MakeUnique<base::MockEntropyProvider>());
  variations::testing::ClearAllVariationParams();

  std::map<std::string, std::string> field_trial_params;
  variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
  base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");

  command_line_.AppendSwitch("disable-quic");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_FALSE(params_.enable_quic);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       EnableQuicFromCommandLine) {
  command_line_.AppendSwitch("enable-quic");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_TRUE(params_.enable_quic);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       QuicVersionFromCommandLine) {
  command_line_.AppendSwitch("enable-quic");
  std::string version =
      net::QuicVersionToString(net::AllSupportedVersions().back());
  command_line_.AppendSwitchASCII("quic-version", version);

  ConfigureParamsFromFieldTrialsAndCommandLine();

  net::QuicVersionVector supported_versions;
  supported_versions.push_back(net::AllSupportedVersions().back());
  EXPECT_EQ(supported_versions, params_.quic_supported_versions);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       QuicConnectionOptionsFromCommandLine) {
  command_line_.AppendSwitch("enable-quic");
  command_line_.AppendSwitchASCII("quic-connection-options", "TIME,TBBR,REJ");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  net::QuicTagVector options;
  options.push_back(net::kTIME);
  options.push_back(net::kTBBR);
  options.push_back(net::kREJ);
  EXPECT_EQ(options, params_.quic_connection_options);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       QuicOriginsToForceQuicOn) {
  command_line_.AppendSwitch("enable-quic");
  command_line_.AppendSwitchASCII("origin-to-force-quic-on",
                                  "www.example.com:443, www.example.org:443");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_EQ(2u, params_.origins_to_force_quic_on.size());
  EXPECT_TRUE(
      base::ContainsKey(params_.origins_to_force_quic_on,
                        net::HostPortPair::FromString("www.example.com:443")));
  EXPECT_TRUE(
      base::ContainsKey(params_.origins_to_force_quic_on,
                        net::HostPortPair::FromString("www.example.org:443")));
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       QuicOriginsToForceQuicOnAll) {
  command_line_.AppendSwitch("enable-quic");
  command_line_.AppendSwitchASCII("origin-to-force-quic-on", "*");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_EQ(1u, params_.origins_to_force_quic_on.size());
  EXPECT_TRUE(
      base::ContainsKey(params_.origins_to_force_quic_on, net::HostPortPair()));
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       QuicDisallowedByPolicy) {
  command_line_.AppendSwitch("enable-quic");
  is_quic_allowed_by_policy_ = false;

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_FALSE(params_.enable_quic);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest, QuicMaxPacketLength) {
  command_line_.AppendSwitch("enable-quic");
  command_line_.AppendSwitchASCII("quic-max-packet-length", "1450");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_EQ(1450u, params_.quic_max_packet_length);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       EnableUserAlternateProtocolPorts) {
  command_line_.AppendSwitch("enable-user-controlled-alternate-protocol-ports");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_TRUE(params_.enable_user_alternate_protocol_ports);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
       IgnoreCertificateErrors) {
  command_line_.AppendSwitch("ignore-certificate-errors");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_TRUE(params_.ignore_certificate_errors);
}

TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest, TestingFixedPort) {
  command_line_.AppendSwitchASCII("testing-fixed-http-port", "42");
  command_line_.AppendSwitchASCII("testing-fixed-https-port", "137");

  ConfigureParamsFromFieldTrialsAndCommandLine();

  EXPECT_EQ(42u, params_.testing_fixed_http_port);
  EXPECT_EQ(137u, params_.testing_fixed_https_port);
}

}  // namespace test
