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

#include "components/variations/service/variations_service.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_command_line.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "base/version.h"
#include "base/version_info/version_info.h"
#include "components/metrics/clean_exit_beacon.h"
#include "components/metrics/client_info.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics/test/test_enabled_state_provider.h"
#include "components/prefs/testing_pref_service.h"
#include "components/variations/pref_names.h"
#include "components/variations/proto/study.pb.h"
#include "components/variations/proto/variations_seed.pb.h"
#include "components/variations/scoped_variations_ids_provider.h"
#include "components/variations/variations_seed_simulator.h"
#include "components/variations/variations_switches.h"
#include "components/version_info/channel.h"
#include "components/web_resource/resource_request_allowed_notifier_test_util.h"
#include "net/base/mock_network_change_notifier.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace variations {
namespace {

// The below seed and signature pair were generated using the server's
// private key.
const char kBase64SeedData[] =
    "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p"
    "Zm9ybWl0eS1UcmlhbC0xMC1QZXJjZW50GICckqUFOAFCB2RlZmF1bHRKCwoHZGVmYXVsdBAB"
    "SgwKCGdyb3VwXzAxEAFKDAoIZ3JvdXBfMDIQAUoMCghncm91cF8wMxABSgwKCGdyb3VwXzA0"
    "EAFKDAoIZ3JvdXBfMDUQAUoMCghncm91cF8wNhABSgwKCGdyb3VwXzA3EAFKDAoIZ3JvdXBf"
    "MDgQAUoMCghncm91cF8wORAB";
const char kBase64SeedSignature[] =
    "MEQCIDD1IVxjzWYncun+9IGzqYjZvqxxujQEayJULTlbTGA/AiAr0oVmEgVUQZBYq5VLOSvy"
    "96JkMYgzTkHPwbv7K/CmgA==";

// TODO(crbug.com/40742801): Remove when fake VariationsServiceClient created.
class TestVariationsServiceClient : public VariationsServiceClient {
 public:
  TestVariationsServiceClient() {
    test_shared_loader_factory_ =
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            &test_url_loader_factory_);
  }

  TestVariationsServiceClient(const TestVariationsServiceClient&) = delete;
  TestVariationsServiceClient& operator=(const TestVariationsServiceClient&) =
      delete;

  ~TestVariationsServiceClient() override = default;

  // VariationsServiceClient:
  base::Version GetVersionForSimulation() override { return base::Version(); }
  scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory()
      override {
    return test_shared_loader_factory_;
  }
  network_time::NetworkTimeTracker* GetNetworkTimeTracker() override {
    return nullptr;
  }
  bool OverridesRestrictParameter(std::string* parameter) override {
    if (restrict_parameter_.empty()) {
      return false;
    }
    *parameter = restrict_parameter_;
    return true;
  }
  bool IsEnterprise() override { return false; }
  void RemoveGoogleGroupsFromPrefsForDeletedProfiles(
      PrefService* local_state) override {}

  void set_restrict_parameter(const std::string& value) {
    restrict_parameter_ = value;
  }

  void set_channel(version_info::Channel channel) { channel_ = channel; }

  network::TestURLLoaderFactory* test_url_loader_factory() {
    return &test_url_loader_factory_;
  }

 private:
  // VariationsServiceClient:
  version_info::Channel GetChannel() override { return channel_; }

  std::string restrict_parameter_;
  version_info::Channel channel_ = version_info::Channel::UNKNOWN;
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
};

// A test class used to validate expected functionality in VariationsService.
class TestVariationsService : public VariationsService {
 public:
  TestVariationsService(
      std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier,
      PrefService* local_state,
      metrics::MetricsStateManager* state_manager,
      bool use_secure_url)
      : VariationsService(std::make_unique<TestVariationsServiceClient>(),
                          std::move(test_notifier),
                          local_state,
                          state_manager,
                          UIStringOverrider()),
        intercepts_fetch_(true),
        fetch_attempted_(false),
        latest_serial_number_(""),
        seed_stores_succeed_(true),
        seed_stored_(false),
        delta_compressed_seed_(false),
        gzip_compressed_seed_(false) {
    interception_url_ =
        GetVariationsServerURL(use_secure_url ? USE_HTTPS : USE_HTTP);
    set_variations_server_url(interception_url_);
  }

  TestVariationsService(const TestVariationsService&) = delete;
  TestVariationsService& operator=(const TestVariationsService&) = delete;

  ~TestVariationsService() override = default;

  GURL interception_url() { return interception_url_; }
  void set_intercepts_fetch(bool value) { intercepts_fetch_ = value; }
  void set_insecure_url(const GURL& url) {
    set_insecure_variations_server_url(url);
  }
  void set_last_request_was_retry(bool was_retry) {
    set_last_request_was_http_retry(was_retry);
  }
  void set_latest_serial_number(const std::string& serial_number) {
    latest_serial_number_ = serial_number;
  }
  void set_seed_stores_succeed(bool value) { seed_stores_succeed_ = value; }
  bool fetch_attempted() const { return fetch_attempted_; }
  bool seed_stored() const { return seed_stored_; }
  const std::string& stored_country() const { return stored_country_; }
  bool delta_compressed_seed() const { return delta_compressed_seed_; }
  bool gzip_compressed_seed() const { return gzip_compressed_seed_; }

  bool CallMaybeRetryOverHTTP() { return CallMaybeRetryOverHTTPForTesting(); }

  const std::string& GetLatestSerialNumber() override {
    return latest_serial_number_;
  }

  void DoActualFetch() override {
    if (intercepts_fetch_) {
      fetch_attempted_ = true;
      return;
    }

    VariationsService::DoActualFetch();
    base::RunLoop().RunUntilIdle();
  }

  bool DoFetchFromURL(const GURL& url, bool is_http_retry) override {
    if (intercepts_fetch_) {
      fetch_attempted_ = true;
      return true;
    }

    return VariationsService::DoFetchFromURL(url, is_http_retry);
  }

  void StoreSeed(std::string seed_data,
                 std::string seed_signature,
                 std::string country_code,
                 base::Time date_fetched,
                 bool is_delta_compressed,
                 bool is_gzip_compressed) override {
    seed_stored_ = true;
    stored_seed_data_ = seed_data;
    stored_country_ = country_code;
    delta_compressed_seed_ = is_delta_compressed;
    gzip_compressed_seed_ = is_gzip_compressed;
    OnSeedStoreResult(is_delta_compressed, seed_stores_succeed_,
                      VariationsSeed());
  }

  TestVariationsServiceClient* client() {
    return static_cast<TestVariationsServiceClient*>(
        VariationsService::client());
  }

  network::TestURLLoaderFactory* test_url_loader_factory() {
    return client()->test_url_loader_factory();
  }

 private:
  GURL interception_url_;
  bool intercepts_fetch_;
  bool fetch_attempted_;
  std::string latest_serial_number_;
  bool seed_stores_succeed_;
  bool seed_stored_;
  std::string stored_seed_data_;
  std::string stored_country_;
  bool delta_compressed_seed_;
  bool gzip_compressed_seed_;
};

class TestVariationsServiceObserver : public VariationsService::Observer {
 public:
  TestVariationsServiceObserver()
      : best_effort_changes_notified_(0), crticial_changes_notified_(0) {}

  TestVariationsServiceObserver(const TestVariationsServiceObserver&) = delete;
  TestVariationsServiceObserver& operator=(
      const TestVariationsServiceObserver&) = delete;

  ~TestVariationsServiceObserver() override = default;

  void OnExperimentChangesDetected(Severity severity) override {
    switch (severity) {
      case BEST_EFFORT:
        ++best_effort_changes_notified_;
        break;
      case CRITICAL:
        ++crticial_changes_notified_;
        break;
    }
  }

  int best_effort_changes_notified() const {
    return best_effort_changes_notified_;
  }

  int crticial_changes_notified() const { return crticial_changes_notified_; }

 private:
  // Number of notification received with BEST_EFFORT severity.
  int best_effort_changes_notified_;

  // Number of notification received with CRITICAL severity.
  int crticial_changes_notified_;
};

// Constants used to create the test seed.
const char kTestSeedStudyName[] = "test";
const char kTestSeedExperimentName[] = "abc";
const int kTestSeedExperimentProbability = 100;
const char kTestSeedSerialNumber[] = "123";

// Populates |seed| with simple test data. The resulting seed will contain one
// study called "test", which contains one experiment called "abc" with
// probability weight 100. |seed|'s study field will be cleared before adding
// the new study.
VariationsSeed CreateTestSeed() {
  VariationsSeed seed;
  Study* study = seed.add_study();
  study->set_name(kTestSeedStudyName);
  study->set_default_experiment_name(kTestSeedExperimentName);
  Study_Experiment* experiment = study->add_experiment();
  experiment->set_name(kTestSeedExperimentName);
  experiment->set_probability_weight(kTestSeedExperimentProbability);
  seed.set_serial_number(kTestSeedSerialNumber);
  return seed;
}

// Serializes |seed| to protobuf binary format.
std::string SerializeSeed(const VariationsSeed& seed) {
  std::string serialized_seed;
  seed.SerializeToString(&serialized_seed);
  return serialized_seed;
}

// Adds an OK response to the test_url_loader_factory with IM headers.
void AddOKResponseWithIM(
    const GURL& interception_url,
    const std::string& body,
    const std::string& im,
    network::TestURLLoaderFactory* test_url_loader_factory) {
  std::string headers("HTTP/1.1 200 OK\n\n");
  auto head = network::mojom::URLResponseHead::New();
  head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
      net::HttpUtil::AssembleRawHeaders(headers));
  if (!im.empty())
    head->headers->SetHeader("IM", im);
  network::URLLoaderCompletionStatus status;
  status.decoded_body_length = body.size();
  test_url_loader_factory->AddResponse(interception_url, std::move(head), body,
                                       status);
}

}  // namespace

class VariationsServiceTest : public ::testing::Test {
 protected:
  VariationsServiceTest()
      : network_tracker_(network::TestNetworkConnectionTracker::GetInstance()),
        enabled_state_provider_(
            new metrics::TestEnabledStateProvider(false, false)) {
    metrics::MetricsStateManager::RegisterPrefs(prefs_.registry());
    VariationsService::RegisterPrefs(prefs_.registry());
  }

  VariationsServiceTest(const VariationsServiceTest&) = delete;
  VariationsServiceTest& operator=(const VariationsServiceTest&) = delete;

  metrics::MetricsStateManager* GetMetricsStateManager() {
    // Lazy-initialize the metrics_state_manager so that it correctly reads the
    // stability state from prefs after tests have a chance to initialize it.
    if (!metrics_state_manager_) {
      metrics_state_manager_ = metrics::MetricsStateManager::Create(
          &prefs_, enabled_state_provider_.get(), std::wstring(),
          base::FilePath());
      metrics_state_manager_->InstantiateFieldTrialList();
    }
    return metrics_state_manager_.get();
  }

 protected:
  TestingPrefServiceSimple prefs_;
  raw_ptr<network::TestNetworkConnectionTracker> network_tracker_;

 private:
  base::test::TaskEnvironment task_environment_;
  variations::test::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
      variations::VariationsIdsProvider::Mode::kUseSignedInState};
  std::unique_ptr<metrics::TestEnabledStateProvider> enabled_state_provider_;
  std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_;
};

TEST_F(VariationsServiceTest, GetVariationsServerURL) {
  const std::string default_variations_url =
      VariationsService::GetDefaultVariationsServerURLForTesting();

  std::string value;
  std::unique_ptr<TestVariationsServiceClient> client =
      std::make_unique<TestVariationsServiceClient>();
  TestVariationsServiceClient* raw_client = client.get();
  VariationsService service(
      std::move(client),
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), UIStringOverrider());
  GURL url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                               base::CompareCase::SENSITIVE));
  EXPECT_FALSE(net::GetValueForKeyInQuery(url, "restrict", &value));
  // There should be a fallback URL since restrict mode is not set.
  EXPECT_NE(GURL(),
            service.GetVariationsServerURL(TestVariationsService::USE_HTTP));

  prefs_.SetString(prefs::kVariationsRestrictParameter, "restricted");
  url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                               base::CompareCase::SENSITIVE));
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
  EXPECT_EQ("restricted", value);
  // No fallback URL because restrict mode is set.
  EXPECT_EQ(GURL(),
            service.GetVariationsServerURL(TestVariationsService::USE_HTTP));

  // A client override should take precedence over what's in prefs_.
  raw_client->set_restrict_parameter("client");
  url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                               base::CompareCase::SENSITIVE));
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
  EXPECT_EQ("client", value);
  // No fallback URL because restrict mode is set.
  EXPECT_EQ(GURL(),
            service.GetVariationsServerURL(TestVariationsService::USE_HTTP));

  // The value set via SetRestrictMode() should take precedence over what's
  // in prefs_ and a client override.
  service.SetRestrictMode("override");
  url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                               base::CompareCase::SENSITIVE));
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
  EXPECT_EQ("override", value);
  // No fallback URL because restrict mode is set.
  EXPECT_EQ(GURL(),
            service.GetVariationsServerURL(TestVariationsService::USE_HTTP));
}

TEST_F(VariationsServiceTest, VariationsURLHasParams) {
  std::unique_ptr<TestVariationsServiceClient> client =
      std::make_unique<TestVariationsServiceClient>();
  TestVariationsServiceClient* raw_client = client.get();
  VariationsService service(
      std::move(client),
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), UIStringOverrider());
  raw_client->set_channel(version_info::Channel::UNKNOWN);
  GURL url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);

  // Corpus param should not be present by default.
  std::string corpus;
  EXPECT_FALSE(net::GetValueForKeyInQuery(url, "corpus", &corpus));

  std::string osname;
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "osname", &osname));
  EXPECT_FALSE(osname.empty());

  std::string milestone;
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "milestone", &milestone));
  EXPECT_FALSE(milestone.empty());

  // Channel param should not be present for UNKNOWN channel.
  std::string channel;
  EXPECT_FALSE(net::GetValueForKeyInQuery(url, "channel", &channel));
  EXPECT_TRUE(channel.empty());

  raw_client->set_channel(version_info::Channel::STABLE);
  url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "channel", &channel));
  EXPECT_FALSE(channel.empty());

  // Corpus param should be present if set via command line.
  base::test::ScopedCommandLine scoped_command_line;
  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
      variations::switches::kVariationsSeedCorpus, "test_corpus");
  url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS);
  EXPECT_TRUE(net::GetValueForKeyInQuery(url, "corpus", &corpus));
  EXPECT_EQ(corpus, "test_corpus");
}

TEST_F(VariationsServiceTest, RequestsInitiallyNotAllowed) {
  std::unique_ptr<net::test::MockNetworkChangeNotifier>
      network_change_notifier = net::test::MockNetworkChangeNotifier::Create();
  // Pass ownership to TestVariationsService, but keep a weak pointer to
  // manipulate it for this test.
  std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier =
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_);
  web_resource::TestRequestAllowedNotifier* raw_notifier = test_notifier.get();
  TestVariationsService test_service(std::move(test_notifier), &prefs_,
                                     GetMetricsStateManager(), true);
  test_service.InitResourceRequestedAllowedNotifier();

  // Force the notifier to initially disallow requests.
  raw_notifier->SetRequestsAllowedOverride(false);
  test_service.StartRepeatedVariationsSeedFetch();
  EXPECT_FALSE(test_service.fetch_attempted());

  raw_notifier->NotifyObserver();
  EXPECT_TRUE(test_service.fetch_attempted());
}

TEST_F(VariationsServiceTest, RequestsInitiallyAllowed) {
  // Pass ownership to TestVariationsService, but keep a weak pointer to
  // manipulate it for this test.
  std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier =
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_);
  web_resource::TestRequestAllowedNotifier* raw_notifier = test_notifier.get();
  TestVariationsService test_service(std::move(test_notifier), &prefs_,
                                     GetMetricsStateManager(), true);

  raw_notifier->SetRequestsAllowedOverride(true);
  test_service.StartRepeatedVariationsSeedFetch();
  EXPECT_TRUE(test_service.fetch_attempted());
}

TEST_F(VariationsServiceTest, SeedStoredWhenOKStatus) {
  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);

  EXPECT_FALSE(service.seed_stored());

  service.test_url_loader_factory()->AddResponse(
      service.interception_url().spec(), SerializeSeed(CreateTestSeed()));
  service.set_intercepts_fetch(false);
  service.DoActualFetch();

  EXPECT_TRUE(service.seed_stored());
}

TEST_F(VariationsServiceTest, SeedNotStoredWhenNonOKStatus) {
  const net::HttpStatusCode non_ok_status_codes[] = {
      net::HTTP_NO_CONTENT,          net::HTTP_NOT_MODIFIED,
      net::HTTP_NOT_FOUND,           net::HTTP_INTERNAL_SERVER_ERROR,
      net::HTTP_SERVICE_UNAVAILABLE,
  };

  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);
  for (const net::HttpStatusCode code : non_ok_status_codes) {
    EXPECT_TRUE(prefs_.FindPreference(prefs::kVariationsCompressedSeed)
                    ->IsDefaultValue());
    service.test_url_loader_factory()->ClearResponses();
    service.test_url_loader_factory()->AddResponse(
        service.interception_url().spec(), "", code);
    service.DoActualFetch();

    EXPECT_TRUE(prefs_.FindPreference(prefs::kVariationsCompressedSeed)
                    ->IsDefaultValue());
  }
}

TEST_F(VariationsServiceTest, RequestGzipCompressedSeed) {
  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);
  net::HttpRequestHeaders intercepted_headers;
  service.test_url_loader_factory()->AddResponse(
      service.interception_url().spec(), "");
  service.test_url_loader_factory()->SetInterceptor(
      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
        intercepted_headers = request.headers;
      }));
  service.DoActualFetch();

  EXPECT_THAT(intercepted_headers.GetHeader("A-IM"),
              ::testing::Optional(std::string("gzip")));
}

TEST_F(VariationsServiceTest, RequestDeltaCompressedSeed) {
  VariationsService::EnableFetchForTesting();

  std::string serialized_seed = SerializeSeed(CreateTestSeed());

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);
  net::HttpRequestHeaders intercepted_headers;
  service.test_url_loader_factory()->SetInterceptor(
      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
        intercepted_headers = request.headers;
      }));

  // Set a serial number to allow delta compression.
  service.set_latest_serial_number("abc");

  // Prepare a delta response that fails to store.
  service.set_seed_stores_succeed(false);
  AddOKResponseWithIM(service.interception_url(), serialized_seed, "x-bm",
                      service.test_url_loader_factory());
  service.DoActualFetch();

  // Make sure the initial request was generated with correct delta headers.
  EXPECT_THAT(intercepted_headers.GetHeader("A-IM"),
              ::testing::Optional(std::string("x-bm,gzip")));
  EXPECT_THAT(intercepted_headers.GetHeader("If-None-Match"),
              ::testing::Optional(std::string("abc")));

  // Do a retry.
  service.set_seed_stores_succeed(true);
  AddOKResponseWithIM(service.interception_url(), serialized_seed, "",
                      service.test_url_loader_factory());
  service.DoActualFetch();

  // The retry request should not request delta compression.
  EXPECT_THAT(intercepted_headers.GetHeader("A-IM"),
              ::testing::Optional(std::string("gzip")));
  // It should still provide the serial number.
  EXPECT_THAT(intercepted_headers.GetHeader("If-None-Match"),
              ::testing::Optional(std::string("abc")));
}

TEST_F(VariationsServiceTest, InstanceManipulations) {
  struct {
    std::string im;
    bool delta_compressed;
    bool gzip_compressed;
    bool seed_stored;
  } cases[] = {
      {"", false, false, true},
      {"gzip", false, true, true},
      {"x-bm", true, false, true},
      {"x-bm,gzip", true, true, true},
      {" x-bm, gzip", true, true, true},
      {"gzip,x-bm", false, false, false},
      {"deflate,x-bm,gzip", false, false, false},
  };

  std::string serialized_seed = SerializeSeed(CreateTestSeed());
  VariationsService::EnableFetchForTesting();
  for (const auto& test_case : cases) {
    TestVariationsService service(
        std::make_unique<web_resource::TestRequestAllowedNotifier>(
            &prefs_, network_tracker_),
        &prefs_, GetMetricsStateManager(), true);
    service.set_intercepts_fetch(false);

    AddOKResponseWithIM(service.interception_url(), serialized_seed,
                        test_case.im, service.test_url_loader_factory());

    service.DoActualFetch();

    EXPECT_EQ(test_case.seed_stored, service.seed_stored());
    EXPECT_EQ(test_case.delta_compressed, service.delta_compressed_seed());
    EXPECT_EQ(test_case.gzip_compressed, service.gzip_compressed_seed());
  }
}

TEST_F(VariationsServiceTest, CountryHeader) {
  std::string serialized_seed = SerializeSeed(CreateTestSeed());
  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  EXPECT_FALSE(service.seed_stored());
  service.set_intercepts_fetch(false);

  std::string headers("HTTP/1.1 200 OK\n\n");
  auto head = network::mojom::URLResponseHead::New();
  head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
      net::HttpUtil::AssembleRawHeaders(headers));
  head->headers->SetHeader("X-Country", "test");
  network::URLLoaderCompletionStatus status;
  status.decoded_body_length = serialized_seed.size();
  service.test_url_loader_factory()->AddResponse(
      service.interception_url(), std::move(head), serialized_seed, status);

  service.DoActualFetch();

  EXPECT_TRUE(service.seed_stored());
  EXPECT_EQ("test", service.stored_country());
}

TEST_F(VariationsServiceTest, Observer) {
  VariationsService service(
      std::make_unique<TestVariationsServiceClient>(),
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), UIStringOverrider());

  struct TestCase {
    int normal_count;
    int best_effort_count;
    int critical_count;
    int expected_best_effort_notifications;
    int expected_crtical_notifications;
  } cases[] = {
      {0, 0, 0, 0, 0},  {1, 0, 0, 0, 0}, {10, 0, 0, 0, 0}, {0, 1, 0, 1, 0},
      {0, 10, 0, 1, 0}, {0, 0, 1, 0, 1}, {0, 0, 10, 0, 1}, {0, 1, 1, 0, 1},
      {1, 1, 1, 0, 1},  {1, 1, 0, 1, 0}, {1, 0, 1, 0, 1},
  };

  for (const TestCase& test_case : cases) {
    TestVariationsServiceObserver observer;
    service.AddObserver(&observer);

    SeedSimulationResult result;
    result.normal_group_change_count = test_case.normal_count;
    result.kill_best_effort_group_change_count = test_case.best_effort_count;
    result.kill_critical_group_change_count = test_case.critical_count;
    service.NotifyObservers(result);

    EXPECT_EQ(test_case.expected_best_effort_notifications,
              observer.best_effort_changes_notified());
    EXPECT_EQ(test_case.expected_crtical_notifications,
              observer.crticial_changes_notified());

    service.RemoveObserver(&observer);
  }
}

TEST_F(VariationsServiceTest, GetStoredPermanentCountry) {
  struct {
    // The command line overridden country, empty if the
    // kVariationsOverrideCountry switch isn't passed in
    const std::string override_country;
    // The old overridden country, empty string if the pref isn't set initially.
    const std::string permanent_overridden_country_before;
    // Comma separated list, NULL if the pref isn't set initially.
    const std::string permanent_consistency_country_before;
    const std::string expected_country;
  } test_cases[] = {
      {"", "", "<VERSION>,us", "us"},
      {"", "us", "<VERSION>,us", "us"},
      {"", "ca", "<VERSION>,us", "ca"},
      {"", "ca", "", "ca"},
      {"gb", "", "<VERSION>,us", "gb"},
      {"gb", "us", "<VERSION>,us", "gb"},
      {"gb", "ca", "<VERSION>,us", "gb"},
      {"gb", "ca", "", "gb"},
  };

  for (const auto& test : test_cases) {
    TestVariationsService service(
        std::make_unique<web_resource::TestRequestAllowedNotifier>(
            &prefs_, network_tracker_),
        &prefs_, GetMetricsStateManager(), true);

    if (!test.override_country.empty()) {
      base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
          switches::kVariationsOverrideCountry, test.override_country);
    }

    if (test.permanent_overridden_country_before.empty()) {
      prefs_.ClearPref(prefs::kVariationsPermanentOverriddenCountry);
    } else {
      prefs_.SetString(prefs::kVariationsPermanentOverriddenCountry,
                       test.permanent_overridden_country_before);
    }

    if (test.permanent_consistency_country_before.empty()) {
      prefs_.ClearPref(prefs::kVariationsPermanentConsistencyCountry);
    } else {
      std::string version_number(version_info::GetVersionNumber());
      base::Value::List list_value;
      for (const std::string& component :
           base::SplitString(test.permanent_consistency_country_before, ",",
                             base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
        if (component == "<VERSION>") {
          // Replace version placeholder
          list_value.Append(version_number);
        } else {
          list_value.Append(component);
        }
      }
      prefs_.SetList(prefs::kVariationsPermanentConsistencyCountry,
                     std::move(list_value));
    }

    VariationsSeed seed(CreateTestSeed());
    // GetClientFilterableStateForVersion needs to be called before
    // service.GetStoredPermanentCountry can be used in tests.
    service.GetClientFilterableStateForVersion();

    EXPECT_EQ(test.expected_country, service.GetStoredPermanentCountry())
        << test.override_country << ", "
        << test.permanent_overridden_country_before << ", "
        << test.permanent_consistency_country_before;
  }
}

TEST_F(VariationsServiceTest, OverrideStoredPermanentCountry) {
  const std::string kPrefCa = "ca";
  const std::string kPrefUs = "us";

  struct {
    // The old overridden country, empty string if the pref isn't set initially.
    const std::string pref_value_before;
    const std::string country_code_override;
    // The expected override country.
    const std::string expected_pref_value_after;
    // Is the pref expected to be updated or not.
    const bool has_updated;
  } test_cases[] = {
      {kPrefUs, "ca", kPrefCa, true},  {kPrefUs, "CA", kPrefCa, true},
      {kPrefUs, "us", kPrefUs, false}, {kPrefUs, "", "", true},
      {"", "ca", kPrefCa, true},
  };

  for (const auto& test : test_cases) {
    TestVariationsService service(
        std::make_unique<web_resource::TestRequestAllowedNotifier>(
            &prefs_, network_tracker_),
        &prefs_, GetMetricsStateManager(), true);

    if (test.pref_value_before.empty()) {
      prefs_.ClearPref(prefs::kVariationsPermanentOverriddenCountry);
    } else {
      prefs_.SetString(prefs::kVariationsPermanentOverriddenCountry,
                       test.pref_value_before);
    }

    VariationsSeed seed(CreateTestSeed());

    EXPECT_EQ(test.has_updated, service.OverrideStoredPermanentCountry(
                                    test.country_code_override))
        << test.pref_value_before << ", " << test.country_code_override;

    const std::string pref_value =
        prefs_.GetString(prefs::kVariationsPermanentOverriddenCountry);
    EXPECT_EQ(test.expected_pref_value_after, pref_value)
        << test.pref_value_before << ", " << test.country_code_override;
  }
}

TEST_F(VariationsServiceTest, SafeMode_StartingRequestIncrementsFetchFailures) {
  prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 1);
  VariationsService::EnableFetchForTesting();

  // Create a variations service and start the fetch.
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);
  service.DoActualFetch();

  EXPECT_EQ(2, prefs_.GetInteger(prefs::kVariationsFailedToFetchSeedStreak));
}

TEST_F(VariationsServiceTest, SafeMode_SuccessfulFetchClearsFailureStreaks) {
  prefs_.SetInteger(prefs::kVariationsCrashStreak, 2);
  prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 1);

  VariationsService::EnableFetchForTesting();

  std::unique_ptr<net::test::MockNetworkChangeNotifier>
      network_change_notifier = net::test::MockNetworkChangeNotifier::Create();

  // Create a variations service and perform a successful fetch.
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);

  std::string response;
  ASSERT_TRUE(base::Base64Decode(kBase64SeedData, &response));

  std::string headers("HTTP/1.1 200 OK\n\n");
  auto head = network::mojom::URLResponseHead::New();
  head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
      net::HttpUtil::AssembleRawHeaders(headers));
  head->headers->SetHeader("X-Seed-Signature", kBase64SeedSignature);
  network::URLLoaderCompletionStatus status;
  status.decoded_body_length = response.size();
  service.test_url_loader_factory()->AddResponse(
      service.interception_url(), std::move(head), response, status);

  service.DoActualFetch();

  // Verify that the streaks were reset.
  EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsCrashStreak));
  EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsFailedToFetchSeedStreak));
}

TEST_F(VariationsServiceTest, SafeMode_NotModifiedFetchClearsFailureStreaks) {
  prefs_.SetInteger(prefs::kVariationsCrashStreak, 2);
  prefs_.SetInteger(prefs::kVariationsFailedToFetchSeedStreak, 1);
  VariationsService::EnableFetchForTesting();

  // Create a variations service and perform a successful fetch.
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);

  std::string headers("HTTP/1.1 304 Not Modified\n\n");
  auto head = network::mojom::URLResponseHead::New();
  head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
      net::HttpUtil::AssembleRawHeaders(headers));
  network::URLLoaderCompletionStatus status;
  service.test_url_loader_factory()->AddResponse(service.interception_url(),
                                                 std::move(head), "", status);

  service.DoActualFetch();

  EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsCrashStreak));
  EXPECT_EQ(0, prefs_.GetInteger(prefs::kVariationsFailedToFetchSeedStreak));
}

TEST_F(VariationsServiceTest, FieldTrialCreatorInitializedCorrectly) {
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);

  // Call will crash in service's VariationsFieldTrialCreator if not initialized
  // correctly.
  service.GetClientFilterableStateForVersion();
}

TEST_F(VariationsServiceTest, RetryOverHTTPIfURLisSet) {
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(true);
  service.set_last_request_was_retry(false);
  service.set_insecure_url(GURL("http://example.test"));
  EXPECT_TRUE(service.CallMaybeRetryOverHTTP());
  EXPECT_TRUE(service.fetch_attempted());
}

TEST_F(VariationsServiceTest, DoNotRetryAfterARetry) {
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(true);
  service.set_last_request_was_retry(true);
  service.set_insecure_url(GURL("http://example.test"));
  EXPECT_FALSE(service.CallMaybeRetryOverHTTP());
  EXPECT_FALSE(service.fetch_attempted());
}

TEST_F(VariationsServiceTest, DoNotRetryIfInsecureURLIsHTTPS) {
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(true);
  service.set_last_request_was_retry(false);
  service.set_insecure_url(GURL("https://example.test"));
  EXPECT_FALSE(service.CallMaybeRetryOverHTTP());
  EXPECT_FALSE(service.fetch_attempted());
}

TEST_F(VariationsServiceTest, SeedStoredWhenRedirected) {
  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);

  EXPECT_FALSE(service.seed_stored());

  net::RedirectInfo redirect_info;
  redirect_info.status_code = 301;
  redirect_info.new_url = service.interception_url();
  network::TestURLLoaderFactory::Redirects redirects;
  redirects.push_back({redirect_info, network::mojom::URLResponseHead::New()});

  auto head = network::CreateURLResponseHead(net::HTTP_OK);

  service.test_url_loader_factory()->AddResponse(
      service.interception_url(), std::move(head),
      SerializeSeed(CreateTestSeed()), network::URLLoaderCompletionStatus(),
      std::move(redirects));

  service.set_intercepts_fetch(false);
  service.DoActualFetch();
  EXPECT_TRUE(service.seed_stored());
}

TEST_F(VariationsServiceTest, NullResponseReceivedWithHTTPOk) {
  VariationsService::EnableFetchForTesting();

  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);

  std::string response;
  ASSERT_TRUE(base::Base64Decode(kBase64SeedData, &response));

  std::string headers("HTTP/1.1 200 OK\n\n");
  auto head = network::mojom::URLResponseHead::New();
  auto http_response_headers = base::MakeRefCounted<net::HttpResponseHeaders>(
      net::HttpUtil::AssembleRawHeaders(headers));
  head->headers = http_response_headers;
  EXPECT_EQ(net::HTTP_OK, http_response_headers->response_code());
  http_response_headers->SetHeader("X-Seed-Signature", kBase64SeedSignature);
  // Set ERR_FAILED status code despite the 200 response code.
  network::URLLoaderCompletionStatus status(net::ERR_FAILED);
  status.decoded_body_length = response.size();
  service.test_url_loader_factory()->AddResponse(
      service.interception_url(), std::move(head), response, status,
      network::TestURLLoaderFactory::Redirects(),
      // We pass the flag below to preserve the 200 code with an error response.
      network::TestURLLoaderFactory::kSendHeadersOnNetworkError);
  EXPECT_EQ(net::HTTP_OK, http_response_headers->response_code());

  base::HistogramTester histogram_tester;
  service.DoActualFetch();
  EXPECT_FALSE(service.seed_stored());
  histogram_tester.ExpectUniqueSample("Variations.SeedFetchResponseOrErrorCode",
                                      net::ERR_FAILED, 1);
}

TEST_F(VariationsServiceTest, VariationsServiceStartsRequestOnNetworkChange) {
  // Verifies VariationsService does a request when network status changes from
  // none to connected. This is a regression test for https://crbug.com/826930.
  VariationsService::EnableFetchForTesting();
  network_tracker_->SetConnectionType(
      network::mojom::ConnectionType::CONNECTION_NONE);
  TestVariationsService service(
      std::make_unique<web_resource::TestRequestAllowedNotifier>(
          &prefs_, network_tracker_),
      &prefs_, GetMetricsStateManager(), true);
  service.set_intercepts_fetch(false);
  service.CancelCurrentRequestForTesting();
  base::RunLoop().RunUntilIdle();
  // Simulate starting Chrome browser.
  service.StartRepeatedVariationsSeedFetchForTesting();
  const int initial_request_count = service.request_count();
  // The variations seed can not be fetched if disconnected. So even we start
  // repeated variations seed fetch (on Chrome start), no requests will be made.
  EXPECT_EQ(0, initial_request_count);

  service.GetResourceRequestAllowedNotifierForTesting()
      ->SetObserverRequestedForTesting(true);
  network_tracker_->SetConnectionType(
      network::mojom::ConnectionType::CONNECTION_WIFI);
  base::RunLoop().RunUntilIdle();

  const int final_request_count = service.request_count();
  // The request will be made once Chrome gets online.
  EXPECT_EQ(initial_request_count + 1, final_request_count);
}

// TODO(isherman): Add an integration test for saving and loading a safe seed,
// once the loading functionality is implemented on the seed store.

}  // namespace variations
