// 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_seed_simulator.h"

#include <stddef.h>

#include <map>

#include "base/metrics/field_trial.h"
#include "components/variations/processed_study.h"
#include "components/variations/proto/study.pb.h"
#include "components/variations/study_filtering.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_seed_processor.h"

namespace variations {

namespace {

// Fills in |current_state| with the current process' active field trials, as a
// map of trial names to group names.
void GetCurrentTrialState(std::map<std::string, std::string>* current_state) {
  base::FieldTrial::ActiveGroups trial_groups;
  base::FieldTrialList::GetActiveFieldTrialGroups(&trial_groups);
  for (size_t i = 0; i < trial_groups.size(); ++i)
    (*current_state)[trial_groups[i].trial_name] = trial_groups[i].group_name;
}

// Simulate group assignment for the specified study with PERMANENT consistency.
// Returns the experiment group that will be selected. Mirrors logic in
// VariationsSeedProcessor::CreateTrialFromStudy().
std::string SimulateGroupAssignment(
    const base::FieldTrial::EntropyProvider& entropy_provider,
    const ProcessedStudy& processed_study) {
  const Study& study = *processed_study.study();
  DCHECK_EQ(Study_Consistency_PERMANENT, study.consistency());

  const double entropy_value =
      entropy_provider.GetEntropyForTrial(study.name(),
                                          study.randomization_seed());
  scoped_refptr<base::FieldTrial> trial(
      base::FieldTrial::CreateSimulatedFieldTrial(
          study.name(), processed_study.total_probability(),
          study.default_experiment_name(), entropy_value));

  for (int i = 0; i < study.experiment_size(); ++i) {
    const Study_Experiment& experiment = study.experiment(i);
    // TODO(asvitkine): This needs to properly handle the case where a group was
    // forced via forcing_flag in the current state, so that it is not treated
    // as changed.
    if (!experiment.has_forcing_flag() &&
        experiment.name() != study.default_experiment_name()) {
      trial->AppendGroup(experiment.name(), experiment.probability_weight());
    }
  }
  if (processed_study.is_expired())
    trial->Disable();
  return trial->group_name();
}

// Finds an experiment in |study| with name |experiment_name| and returns it,
// or NULL if it does not exist.
const Study_Experiment* FindExperiment(const Study& study,
                                       const std::string& experiment_name) {
  for (int i = 0; i < study.experiment_size(); ++i) {
    if (study.experiment(i).name() == experiment_name)
      return &study.experiment(i);
  }
  return NULL;
}

// Checks whether experiment params set for |experiment| on |study| are exactly
// equal to the params registered for the corresponding field trial in the
// current process.
bool VariationParamsAreEqual(const Study& study,
                             const Study_Experiment& experiment) {
  std::map<std::string, std::string> params;
  GetVariationParams(study.name(), &params);

  if (static_cast<int>(params.size()) != experiment.param_size())
    return false;

  for (int i = 0; i < experiment.param_size(); ++i) {
    std::map<std::string, std::string>::const_iterator it =
        params.find(experiment.param(i).name());
    if (it == params.end() || it->second != experiment.param(i).value())
      return false;
  }

  return true;
}

}  // namespace

VariationsSeedSimulator::Result::Result()
    : normal_group_change_count(0),
      kill_best_effort_group_change_count(0),
      kill_critical_group_change_count(0) {
}

VariationsSeedSimulator::Result::~Result() {
}

VariationsSeedSimulator::VariationsSeedSimulator(
    const base::FieldTrial::EntropyProvider& default_entropy_provider,
    const base::FieldTrial::EntropyProvider& low_entropy_provider)
    : default_entropy_provider_(default_entropy_provider),
      low_entropy_provider_(low_entropy_provider) {}

VariationsSeedSimulator::~VariationsSeedSimulator() {
}

VariationsSeedSimulator::Result VariationsSeedSimulator::SimulateSeedStudies(
    const VariationsSeed& seed,
    const std::string& locale,
    const base::Time& reference_date,
    const base::Version& version,
    Study_Channel channel,
    Study_FormFactor form_factor,
    const std::string& hardware_class,
    const std::string& session_consistency_country,
    const std::string& permanent_consistency_country) {
  std::vector<ProcessedStudy> filtered_studies;
  FilterAndValidateStudies(seed, locale, reference_date, version, channel,
                           form_factor, hardware_class,
                           session_consistency_country,
                           permanent_consistency_country, &filtered_studies);

  return ComputeDifferences(filtered_studies);
}

VariationsSeedSimulator::Result VariationsSeedSimulator::ComputeDifferences(
    const std::vector<ProcessedStudy>& processed_studies) {
  std::map<std::string, std::string> current_state;
  GetCurrentTrialState(&current_state);

  Result result;
  for (size_t i = 0; i < processed_studies.size(); ++i) {
    const Study& study = *processed_studies[i].study();
    std::map<std::string, std::string>::const_iterator it =
        current_state.find(study.name());

    // Skip studies that aren't activated in the current state.
    // TODO(asvitkine): This should be handled more intelligently. There are
    // several cases that fall into this category:
    //   1) There's an existing field trial with this name but it is not active.
    //   2) There's an existing expired field trial with this name, which is
    //      also not considered as active.
    //   3) This is a new study config that previously didn't exist.
    // The above cases should be differentiated and handled explicitly.
    if (it == current_state.end())
      continue;

    // Study exists in the current state, check whether its group will change.
    // Note: The logic below does the right thing if study consistency changes,
    // as it doesn't rely on the previous study consistency.
    const std::string& selected_group = it->second;
    ChangeType change_type = NO_CHANGE;
    if (study.consistency() == Study_Consistency_PERMANENT) {
      change_type = PermanentStudyGroupChanged(processed_studies[i],
                                               selected_group);
    } else if (study.consistency() == Study_Consistency_SESSION) {
      change_type = SessionStudyGroupChanged(processed_studies[i],
                                             selected_group);
    }

    switch (change_type) {
      case NO_CHANGE:
        break;
      case CHANGED:
        ++result.normal_group_change_count;
        break;
      case CHANGED_KILL_BEST_EFFORT:
        ++result.kill_best_effort_group_change_count;
        break;
      case CHANGED_KILL_CRITICAL:
        ++result.kill_critical_group_change_count;
        break;
    }
  }

  // TODO(asvitkine): Handle removed studies (i.e. studies that existed in the
  // old seed, but were removed). This will require tracking the set of studies
  // that were created from the original seed.

  return result;
}

VariationsSeedSimulator::ChangeType
VariationsSeedSimulator::ConvertExperimentTypeToChangeType(
    Study_Experiment_Type type) {
  switch (type) {
    case Study_Experiment_Type_NORMAL:
      return CHANGED;
    case Study_Experiment_Type_IGNORE_CHANGE:
      return NO_CHANGE;
    case Study_Experiment_Type_KILL_BEST_EFFORT:
      return CHANGED_KILL_BEST_EFFORT;
    case Study_Experiment_Type_KILL_CRITICAL:
      return CHANGED_KILL_CRITICAL;
  }
  return CHANGED;
}

VariationsSeedSimulator::ChangeType
VariationsSeedSimulator::PermanentStudyGroupChanged(
    const ProcessedStudy& processed_study,
    const std::string& selected_group) {
  const Study& study = *processed_study.study();
  DCHECK_EQ(Study_Consistency_PERMANENT, study.consistency());

  const base::FieldTrial::EntropyProvider& entropy_provider =
      VariationsSeedProcessor::ShouldStudyUseLowEntropy(study)
          ? low_entropy_provider_
          : default_entropy_provider_;

  const std::string simulated_group =
      SimulateGroupAssignment(entropy_provider, processed_study);
  const Study_Experiment* experiment = FindExperiment(study, selected_group);
  if (simulated_group != selected_group) {
    if (experiment)
      return ConvertExperimentTypeToChangeType(experiment->type());
    return CHANGED;
  }

  // Current group exists in the study - check whether its params changed.
  DCHECK(experiment);
  if (!VariationParamsAreEqual(study, *experiment))
    return ConvertExperimentTypeToChangeType(experiment->type());
  return NO_CHANGE;
}

VariationsSeedSimulator::ChangeType
VariationsSeedSimulator::SessionStudyGroupChanged(
    const ProcessedStudy& processed_study,
    const std::string& selected_group) {
  const Study& study = *processed_study.study();
  DCHECK_EQ(Study_Consistency_SESSION, study.consistency());

  const Study_Experiment* experiment = FindExperiment(study, selected_group);
  if (processed_study.is_expired() &&
      selected_group != study.default_experiment_name()) {
    // An expired study will result in the default group being selected - mark
    // it as changed if the current group differs from the default.
    if (experiment)
      return ConvertExperimentTypeToChangeType(experiment->type());
    return CHANGED;
  }

  if (!experiment)
    return CHANGED;
  if (experiment->probability_weight() == 0 &&
      !experiment->has_forcing_flag()) {
    return ConvertExperimentTypeToChangeType(experiment->type());
  }

  // Current group exists in the study - check whether its params changed.
  if (!VariationParamsAreEqual(study, *experiment))
    return ConvertExperimentTypeToChangeType(experiment->type());
  return NO_CHANGE;
}

}  // namespace variations
