// 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 "components/variations/variations_http_header_provider.h"

#include <string>

#include "base/base64.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/proto/client_variations.pb.h"
#include "components/variations/variations_associated_data.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace variations {

namespace {

// Decodes the variations header and extracts the variation ids.
bool ExtractVariationIds(const std::string& variations,
                         std::set<VariationID>* variation_ids,
                         std::set<VariationID>* trigger_ids) {
  std::string serialized_proto;
  if (!base::Base64Decode(variations, &serialized_proto))
    return false;
  ClientVariations proto;
  if (!proto.ParseFromString(serialized_proto))
    return false;
  for (int i = 0; i < proto.variation_id_size(); ++i)
    variation_ids->insert(proto.variation_id(i));
  for (int i = 0; i < proto.trigger_variation_id_size(); ++i)
    trigger_ids->insert(proto.trigger_variation_id(i));
  return true;
}

scoped_refptr<base::FieldTrial> CreateTrialAndAssociateId(
    const std::string& trial_name,
    const std::string& default_group_name,
    IDCollectionKey key,
    VariationID id) {
  scoped_refptr<base::FieldTrial> trial(
      base::FieldTrialList::CreateFieldTrial(trial_name, default_group_name));

  AssociateGoogleVariationID(key, trial->trial_name(), trial->group_name(), id);

  return trial;
}

}  // namespace

class VariationsHttpHeaderProviderTest : public ::testing::Test {
 public:
  VariationsHttpHeaderProviderTest() {}

  ~VariationsHttpHeaderProviderTest() override {}

  void TearDown() override { testing::ClearAllVariationIDs(); }
};

TEST_F(VariationsHttpHeaderProviderTest, ForceVariationIds_Valid) {
  base::test::ScopedTaskEnvironment task_environment;
  VariationsHttpHeaderProvider provider;

  // Valid experiment ids.
  EXPECT_EQ(VariationsHttpHeaderProvider::ForceIdsResult::SUCCESS,
            provider.ForceVariationIds({"12", "456", "t789"}, ""));
  provider.InitVariationIDsCacheIfNeeded();
  std::string variations = provider.GetClientDataHeader(false);
  EXPECT_FALSE(variations.empty());
  std::set<VariationID> variation_ids;
  std::set<VariationID> trigger_ids;
  ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
  EXPECT_TRUE(variation_ids.find(12) != variation_ids.end());
  EXPECT_TRUE(variation_ids.find(456) != variation_ids.end());
  EXPECT_TRUE(trigger_ids.find(789) != trigger_ids.end());
  EXPECT_FALSE(variation_ids.find(789) != variation_ids.end());
}

TEST_F(VariationsHttpHeaderProviderTest, ForceVariationIds_ValidCommandLine) {
  base::test::ScopedTaskEnvironment task_environment;
  VariationsHttpHeaderProvider provider;

  // Valid experiment ids.
  EXPECT_EQ(VariationsHttpHeaderProvider::ForceIdsResult::SUCCESS,
            provider.ForceVariationIds({"12"}, "456,t789"));
  provider.InitVariationIDsCacheIfNeeded();
  std::string variations = provider.GetClientDataHeader(false);
  EXPECT_FALSE(variations.empty());
  std::set<VariationID> variation_ids;
  std::set<VariationID> trigger_ids;
  ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
  EXPECT_TRUE(variation_ids.find(12) != variation_ids.end());
  EXPECT_TRUE(variation_ids.find(456) != variation_ids.end());
  EXPECT_TRUE(trigger_ids.find(789) != trigger_ids.end());
  EXPECT_FALSE(variation_ids.find(789) != variation_ids.end());
}

TEST_F(VariationsHttpHeaderProviderTest, ForceVariationIds_Invalid) {
  base::test::ScopedTaskEnvironment task_environment;
  VariationsHttpHeaderProvider provider;

  // Invalid experiment ids.
  EXPECT_EQ(VariationsHttpHeaderProvider::ForceIdsResult::INVALID_VECTOR_ENTRY,
            provider.ForceVariationIds({"abcd12", "456"}, ""));
  provider.InitVariationIDsCacheIfNeeded();
  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());

  // Invalid trigger experiment id
  EXPECT_EQ(VariationsHttpHeaderProvider::ForceIdsResult::INVALID_VECTOR_ENTRY,
            provider.ForceVariationIds({"12", "tabc456"}, ""));
  provider.InitVariationIDsCacheIfNeeded();
  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());

  // Invalid command-line ids.
  EXPECT_EQ(VariationsHttpHeaderProvider::ForceIdsResult::INVALID_SWITCH_ENTRY,
            provider.ForceVariationIds({"12", "50"}, "tabc456"));
  provider.InitVariationIDsCacheIfNeeded();
  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());
}

TEST_F(VariationsHttpHeaderProviderTest, OnFieldTrialGroupFinalized) {
  base::test::ScopedTaskEnvironment task_environment;
  base::FieldTrialList field_trial_list(nullptr);
  VariationsHttpHeaderProvider provider;
  provider.InitVariationIDsCacheIfNeeded();

  const std::string default_name = "default";
  scoped_refptr<base::FieldTrial> trial_1(CreateTrialAndAssociateId(
      "t1", default_name, GOOGLE_WEB_PROPERTIES, 123));
  ASSERT_EQ(default_name, trial_1->group_name());

  scoped_refptr<base::FieldTrial> trial_2(CreateTrialAndAssociateId(
      "t2", default_name, GOOGLE_WEB_PROPERTIES_TRIGGER, 456));
  ASSERT_EQ(default_name, trial_2->group_name());

  scoped_refptr<base::FieldTrial> trial_3(CreateTrialAndAssociateId(
      "t3", default_name, GOOGLE_WEB_PROPERTIES_SIGNED_IN, 789));
  ASSERT_EQ(default_name, trial_3->group_name());

  // Run the message loop to make sure OnFieldTrialGroupFinalized is called for
  // the two field trials.
  base::RunLoop().RunUntilIdle();

  // Get non-signed in ids.
  {
    std::string variations = provider.GetClientDataHeader(false);
    std::set<VariationID> variation_ids;
    std::set<VariationID> trigger_ids;
    ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
    EXPECT_EQ(1U, variation_ids.size());
    EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
    EXPECT_EQ(1U, trigger_ids.size());
    EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
  }

  // Now, get signed-in ids.
  {
    std::string variations = provider.GetClientDataHeader(true);
    std::set<VariationID> variation_ids;
    std::set<VariationID> trigger_ids;
    ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
    EXPECT_EQ(2U, variation_ids.size());
    EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
    EXPECT_TRUE(variation_ids.find(789) != variation_ids.end());
    EXPECT_EQ(1U, trigger_ids.size());
    EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
  }
}

TEST_F(VariationsHttpHeaderProviderTest, GetVariationsString) {
  base::test::ScopedTaskEnvironment task_environment;
  base::FieldTrialList field_trial_list(nullptr);

  CreateTrialAndAssociateId("t1", "g1", GOOGLE_WEB_PROPERTIES, 123);
  CreateTrialAndAssociateId("t2", "g2", GOOGLE_WEB_PROPERTIES, 124);
  // SIGNED_IN ids shouldn't be included.
  CreateTrialAndAssociateId("t3", "g3", GOOGLE_WEB_PROPERTIES_SIGNED_IN, 125);

  VariationsHttpHeaderProvider provider;
  provider.ForceVariationIds({"100", "200"}, "");
  EXPECT_EQ(" 100 123 124 200 ", provider.GetVariationsString());
}

}  // namespace variations
