// 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/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.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, SetDefaultVariationIds_Valid) {
  base::MessageLoop loop;
  VariationsHttpHeaderProvider provider;

  // Valid experiment ids.
  EXPECT_TRUE(provider.SetDefaultVariationIds({"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, SetDefaultVariationIds_Invalid) {
  base::MessageLoop loop;
  VariationsHttpHeaderProvider provider;

  // Invalid experiment ids.
  EXPECT_FALSE(provider.SetDefaultVariationIds(
      std::vector<std::string>{"abcd12", "456"}));
  provider.InitVariationIDsCacheIfNeeded();
  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());

  // Invalid trigger experiment id
  EXPECT_FALSE(provider.SetDefaultVariationIds(
      std::vector<std::string>{"12", "tabc456"}));
  provider.InitVariationIDsCacheIfNeeded();
  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());
}

TEST_F(VariationsHttpHeaderProviderTest, OnFieldTrialGroupFinalized) {
  base::MessageLoop loop;
  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::MessageLoop loop;
  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;
  std::vector<std::string> ids;
  ids.push_back("100");
  ids.push_back("200");
  provider.SetDefaultVariationIds(ids);
  EXPECT_EQ(" 100 123 124 200 ", provider.GetVariationsString());
}

}  // namespace variations
