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

#include <set>

#include "base/version.h"
#include "components/variations/proto/study.pb.h"

namespace chrome_variations {

namespace {

// Validates the sanity of |study| and computes the total probability.
bool ValidateStudyAndComputeTotalProbability(
    const Study& study,
    base::FieldTrial::Probability* total_probability) {
  // At the moment, a missing default_experiment_name makes the study invalid.
  if (study.default_experiment_name().empty()) {
    DVLOG(1) << study.name() << " has no default experiment defined.";
    return false;
  }
  if (study.filter().has_min_version() &&
      !Version::IsValidWildcardString(study.filter().min_version())) {
    DVLOG(1) << study.name() << " has invalid min version: "
             << study.filter().min_version();
    return false;
  }
  if (study.filter().has_max_version() &&
      !Version::IsValidWildcardString(study.filter().max_version())) {
    DVLOG(1) << study.name() << " has invalid max version: "
             << study.filter().max_version();
    return false;
  }

  const std::string& default_group_name = study.default_experiment_name();
  base::FieldTrial::Probability divisor = 0;

  bool found_default_group = false;
  std::set<std::string> experiment_names;
  for (int i = 0; i < study.experiment_size(); ++i) {
    if (study.experiment(i).name().empty()) {
      DVLOG(1) << study.name() << " is missing experiment " << i << " name";
      return false;
    }
    if (!experiment_names.insert(study.experiment(i).name()).second) {
      DVLOG(1) << study.name() << " has a repeated experiment name "
               << study.experiment(i).name();
      return false;
    }

    if (!study.experiment(i).has_forcing_flag())
      divisor += study.experiment(i).probability_weight();
    if (study.experiment(i).name() == default_group_name)
      found_default_group = true;
  }

  if (!found_default_group) {
    DVLOG(1) << study.name() << " is missing default experiment in its "
             << "experiment list";
    // The default group was not found in the list of groups. This study is not
    // valid.
    return false;
  }

  *total_probability = divisor;
  return true;
}


}  // namespace


ProcessedStudy::ProcessedStudy()
    : study_(NULL), total_probability_(0), is_expired_(false) {
}

ProcessedStudy::~ProcessedStudy() {
}

bool ProcessedStudy::Init(const Study* study, bool is_expired) {
  base::FieldTrial::Probability total_probability = 0;
  if (!ValidateStudyAndComputeTotalProbability(*study, &total_probability))
    return false;

  study_ = study;
  is_expired_ = is_expired;
  total_probability_ = total_probability;
  return true;
}

// static
bool ProcessedStudy::ValidateAndAppendStudy(
    const Study* study,
    bool is_expired,
    std::vector<ProcessedStudy>* processed_studies) {
  ProcessedStudy processed_study;
  if (processed_study.Init(study, is_expired)) {
    processed_studies->push_back(processed_study);
    return true;
  }
  return false;
}

}  // namespace chrome_variations
