// Copyright 2013 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_associated_data.h"

#include <map>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_split.h"
#include "components/variations/variations_http_header_provider.h"

namespace variations {

namespace {

// The internal singleton accessor for the map, used to keep it thread-safe.
class GroupMapAccessor {
 public:
  typedef std::map<ActiveGroupId, VariationID, ActiveGroupIdCompare>
      GroupToIDMap;

  // Retrieve the singleton.
  static GroupMapAccessor* GetInstance() {
    return base::Singleton<GroupMapAccessor>::get();
  }

  // Note that this normally only sets the ID for a group the first time, unless
  // |force| is set to true, in which case it will always override it.
  void AssociateID(IDCollectionKey key,
                   const ActiveGroupId& group_identifier,
                   const VariationID id,
                   const bool force) {
#if !defined(NDEBUG)
    DCHECK_EQ(4, ID_COLLECTION_COUNT);
    // Ensure that at most one of the trigger/non-trigger/signed-in web property
    // IDs are set.
    if (key == GOOGLE_WEB_PROPERTIES || key == GOOGLE_WEB_PROPERTIES_TRIGGER ||
        key == GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
      if (key != GOOGLE_WEB_PROPERTIES)
        DCHECK_EQ(EMPTY_ID, GetID(GOOGLE_WEB_PROPERTIES, group_identifier));
      if (key != GOOGLE_WEB_PROPERTIES_TRIGGER) {
        DCHECK_EQ(EMPTY_ID,
                  GetID(GOOGLE_WEB_PROPERTIES_TRIGGER, group_identifier));
      }
      if (key != GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
        DCHECK_EQ(EMPTY_ID,
                  GetID(GOOGLE_WEB_PROPERTIES_SIGNED_IN, group_identifier));
      }
    }

    // Validate that all collections with this |group_identifier| have the same
    // associated ID.
    for (int i = 0; i < ID_COLLECTION_COUNT; ++i) {
      IDCollectionKey other_key = static_cast<IDCollectionKey>(i);
      if (other_key == key)
        continue;
      VariationID other_id = GetID(other_key, group_identifier);
      DCHECK(other_id == EMPTY_ID || other_id == id);
    }
#endif

    base::AutoLock scoped_lock(lock_);

    GroupToIDMap* group_to_id_map = GetGroupToIDMap(key);
    if (force ||
        group_to_id_map->find(group_identifier) == group_to_id_map->end())
      (*group_to_id_map)[group_identifier] = id;
  }

  VariationID GetID(IDCollectionKey key,
                    const ActiveGroupId& group_identifier) {
    base::AutoLock scoped_lock(lock_);
    GroupToIDMap* group_to_id_map = GetGroupToIDMap(key);
    GroupToIDMap::const_iterator it = group_to_id_map->find(group_identifier);
    if (it == group_to_id_map->end())
      return EMPTY_ID;
    return it->second;
  }

  void ClearAllMapsForTesting() {
    base::AutoLock scoped_lock(lock_);

    for (int i = 0; i < ID_COLLECTION_COUNT; ++i) {
      GroupToIDMap* map = GetGroupToIDMap(static_cast<IDCollectionKey>(i));
      DCHECK(map);
      map->clear();
    }
  }

 private:
  friend struct base::DefaultSingletonTraits<GroupMapAccessor>;

  // Retrieves the GroupToIDMap for |key|.
  GroupToIDMap* GetGroupToIDMap(IDCollectionKey key) {
    return &group_to_id_maps_[key];
  }

  GroupMapAccessor() {
    group_to_id_maps_.resize(ID_COLLECTION_COUNT);
  }
  ~GroupMapAccessor() {}

  base::Lock lock_;
  std::vector<GroupToIDMap> group_to_id_maps_;

  DISALLOW_COPY_AND_ASSIGN(GroupMapAccessor);
};
}  // namespace

void AssociateGoogleVariationID(IDCollectionKey key,
                                const std::string& trial_name,
                                const std::string& group_name,
                                VariationID id) {
  GroupMapAccessor::GetInstance()->AssociateID(
      key, MakeActiveGroupId(trial_name, group_name), id, false);
}

void AssociateGoogleVariationIDForce(IDCollectionKey key,
                                     const std::string& trial_name,
                                     const std::string& group_name,
                                     VariationID id) {
  AssociateGoogleVariationIDForceHashes(
      key, MakeActiveGroupId(trial_name, group_name), id);
}

void AssociateGoogleVariationIDForceHashes(IDCollectionKey key,
                                           const ActiveGroupId& active_group,
                                           VariationID id) {
  GroupMapAccessor::GetInstance()->AssociateID(key, active_group, id, true);
}

VariationID GetGoogleVariationID(IDCollectionKey key,
                                 const std::string& trial_name,
                                 const std::string& group_name) {
  return GetGoogleVariationIDFromHashes(
      key, MakeActiveGroupId(trial_name, group_name));
}

VariationID GetGoogleVariationIDFromHashes(
    IDCollectionKey key,
    const ActiveGroupId& active_group) {
  return GroupMapAccessor::GetInstance()->GetID(key, active_group);
}

bool AssociateVariationParams(
    const std::string& trial_name,
    const std::string& group_name,
    const std::map<std::string, std::string>& params) {
  return base::AssociateFieldTrialParams(trial_name, group_name, params);
}

bool GetVariationParams(const std::string& trial_name,
                        std::map<std::string, std::string>* params) {
  return base::GetFieldTrialParams(trial_name, params);
}

bool GetVariationParamsByFeature(const base::Feature& feature,
                                 std::map<std::string, std::string>* params) {
  return base::GetFieldTrialParamsByFeature(feature, params);
}

std::string GetVariationParamValue(const std::string& trial_name,
                                   const std::string& param_name) {
  return base::GetFieldTrialParamValue(trial_name, param_name);
}

std::string GetVariationParamValueByFeature(const base::Feature& feature,
                                            const std::string& param_name) {
  return base::GetFieldTrialParamValueByFeature(feature, param_name);
}

int GetVariationParamByFeatureAsInt(const base::Feature& feature,
                                    const std::string& param_name,
                                    int default_value) {
  return base::GetFieldTrialParamByFeatureAsInt(feature, param_name,
                                                default_value);
}

double GetVariationParamByFeatureAsDouble(const base::Feature& feature,
                                          const std::string& param_name,
                                          double default_value) {
  return base::GetFieldTrialParamByFeatureAsDouble(feature, param_name,
                                                   default_value);
}

bool GetVariationParamByFeatureAsBool(const base::Feature& feature,
                                      const std::string& param_name,
                                      bool default_value) {
  return base::GetFieldTrialParamByFeatureAsBool(feature, param_name,
                                                 default_value);
}

// Functions below are exposed for testing explicitly behind this namespace.
// They simply wrap existing functions in this file.
namespace testing {

void ClearAllVariationIDs() {
  GroupMapAccessor::GetInstance()->ClearAllMapsForTesting();
}

void ClearAllVariationParams() {
  base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
}

}  // namespace testing

}  // namespace variations
