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

#include <stddef.h>
#include <stdint.h>

#include <set>

#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "components/variations/client_filterable_state.h"

namespace variations {
namespace {

// Converts |date_time| in Study date format to base::Time.
base::Time ConvertStudyDateToBaseTime(int64_t date_time) {
  return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(date_time);
}

}  // namespace

namespace internal {

bool CheckStudyChannel(const Study::Filter& filter, Study::Channel channel) {
  // An empty channel list matches all channels.
  if (filter.channel_size() == 0)
    return true;

  for (int i = 0; i < filter.channel_size(); ++i) {
    if (filter.channel(i) == channel)
      return true;
  }
  return false;
}

bool CheckStudyFormFactor(const Study::Filter& filter,
                          Study::FormFactor form_factor) {
  // Empty whitelist and blacklist signifies matching any form factor.
  if (filter.form_factor_size() == 0 && filter.exclude_form_factor_size() == 0)
    return true;

  // Allow the form_factor if it matches the whitelist.
  // Note if both a whitelist and blacklist are specified, the blacklist is
  // ignored. We do not expect both to be present for Chrome due to server-side
  // checks.
  if (filter.form_factor_size() > 0)
    return base::ContainsValue(filter.form_factor(), form_factor);

  // Omit if we match the blacklist.
  return !base::ContainsValue(filter.exclude_form_factor(), form_factor);
}

bool CheckStudyHardwareClass(const Study::Filter& filter,
                             const std::string& hardware_class) {
  // Empty hardware_class and exclude_hardware_class matches all.
  if (filter.hardware_class_size() == 0 &&
      filter.exclude_hardware_class_size() == 0) {
    return true;
  }

  // Checks if we are supposed to filter for a specified set of
  // hardware_classes. Note that this means this overrides the
  // exclude_hardware_class in case that ever occurs (which it shouldn't).
  if (filter.hardware_class_size() > 0) {
    for (int i = 0; i < filter.hardware_class_size(); ++i) {
      // Check if the entry is a substring of |hardware_class|.
      size_t position = hardware_class.find(filter.hardware_class(i));
      if (position != std::string::npos)
        return true;
    }
    // None of the requested hardware_classes match.
    return false;
  }

  // Omit if matches any of the exclude entries.
  for (int i = 0; i < filter.exclude_hardware_class_size(); ++i) {
    // Check if the entry is a substring of |hardware_class|.
    size_t position = hardware_class.find(
        filter.exclude_hardware_class(i));
    if (position != std::string::npos)
      return false;
  }

  // None of the exclusions match, so this accepts.
  return true;
}

bool CheckStudyLocale(const Study::Filter& filter, const std::string& locale) {
  // Empty locale and exclude_locale lists matches all locales.
  if (filter.locale_size() == 0 && filter.exclude_locale_size() == 0)
    return true;

  // Check if we are supposed to filter for a specified set of countries. Note
  // that this means this overrides the exclude_locale in case that ever occurs
  // (which it shouldn't).
  if (filter.locale_size() > 0)
    return base::ContainsValue(filter.locale(), locale);

  // Omit if matches any of the exclude entries.
  return !base::ContainsValue(filter.exclude_locale(), locale);
}

bool CheckStudyPlatform(const Study::Filter& filter, Study::Platform platform) {
  // An empty platform list matches all platforms.
  if (filter.platform_size() == 0)
    return true;

  for (int i = 0; i < filter.platform_size(); ++i) {
    if (filter.platform(i) == platform)
      return true;
  }
  return false;
}

bool CheckStudyStartDate(const Study::Filter& filter,
                         const base::Time& date_time) {
  if (filter.has_start_date()) {
    const base::Time start_date =
        ConvertStudyDateToBaseTime(filter.start_date());
    return date_time >= start_date;
  }

  return true;
}

bool CheckStudyEndDate(const Study::Filter& filter,
                       const base::Time& date_time) {
  if (filter.has_end_date()) {
    const base::Time end_date = ConvertStudyDateToBaseTime(filter.end_date());
    return end_date >= date_time;
  }

  return true;
}

bool CheckStudyVersion(const Study::Filter& filter,
                       const base::Version& version) {
  if (filter.has_min_version()) {
    if (version.CompareToWildcardString(filter.min_version()) < 0)
      return false;
  }

  if (filter.has_max_version()) {
    if (version.CompareToWildcardString(filter.max_version()) > 0)
      return false;
  }

  return true;
}

bool CheckStudyCountry(const Study::Filter& filter,
                       const std::string& country) {
  // Empty country and exclude_country matches all.
  if (filter.country_size() == 0 && filter.exclude_country_size() == 0)
    return true;

  // Checks if we are supposed to filter for a specified set of countries. Note
  // that this means this overrides the exclude_country in case that ever occurs
  // (which it shouldn't).
  if (filter.country_size() > 0)
    return base::ContainsValue(filter.country(), country);

  // Omit if matches any of the exclude entries.
  return !base::ContainsValue(filter.exclude_country(), country);
}

const std::string& GetClientCountryForStudy(
    const Study& study,
    const ClientFilterableState& client_state) {
  switch (study.consistency()) {
    case Study::SESSION:
      return client_state.session_consistency_country;
    case Study::PERMANENT:
      // Use the saved country for permanent consistency studies. This allows
      // Chrome to use the same country for filtering permanent consistency
      // studies between Chrome upgrades. Since some studies have user-visible
      // effects, this helps to avoid annoying users with experimental group
      // churn while traveling.
      return client_state.permanent_consistency_country;
  }

  // Unless otherwise specified, use an empty country that won't pass any
  // filters that specifically include countries, but will pass any filters
  // that specifically exclude countries.
  return base::EmptyString();
}

bool IsStudyExpired(const Study& study, const base::Time& date_time) {
  if (study.has_expiry_date()) {
    const base::Time expiry_date =
        ConvertStudyDateToBaseTime(study.expiry_date());
    return date_time >= expiry_date;
  }

  return false;
}

bool ShouldAddStudy(const Study& study,
                    const ClientFilterableState& client_state) {
  if (study.has_filter()) {
    if (!CheckStudyChannel(study.filter(), client_state.channel)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to channel.";
      return false;
    }

    if (!CheckStudyFormFactor(study.filter(), client_state.form_factor)) {
      DVLOG(1) << "Filtered out study " << study.name() <<
                  " due to form factor.";
      return false;
    }

    if (!CheckStudyLocale(study.filter(), client_state.locale)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to locale.";
      return false;
    }

    if (!CheckStudyPlatform(study.filter(), client_state.platform)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to platform.";
      return false;
    }

    if (!CheckStudyVersion(study.filter(), client_state.version)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to version.";
      return false;
    }

    if (!CheckStudyStartDate(study.filter(), client_state.reference_date)) {
      DVLOG(1) << "Filtered out study " << study.name() <<
                  " due to start date.";
      return false;
    }

    if (!CheckStudyEndDate(study.filter(), client_state.reference_date)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to end date.";
      return false;
    }

    if (!CheckStudyHardwareClass(study.filter(), client_state.hardware_class)) {
      DVLOG(1) << "Filtered out study " << study.name() <<
                  " due to hardware_class.";
      return false;
    }

    const std::string& country = GetClientCountryForStudy(study, client_state);
    if (!CheckStudyCountry(study.filter(), country)) {
      DVLOG(1) << "Filtered out study " << study.name() << " due to country.";
      return false;
    }
  }

  DVLOG(1) << "Kept study " << study.name() << ".";
  return true;
}

}  // namespace internal

void FilterAndValidateStudies(const VariationsSeed& seed,
                              const ClientFilterableState& client_state,
                              std::vector<ProcessedStudy>* filtered_studies) {
  DCHECK(client_state.version.IsValid());

  // Add expired studies (in a disabled state) only after all the non-expired
  // studies have been added (and do not add an expired study if a corresponding
  // non-expired study got added). This way, if there's both an expired and a
  // non-expired study that applies, the non-expired study takes priority.
  std::set<std::string> created_studies;
  std::vector<const Study*> expired_studies;

  for (int i = 0; i < seed.study_size(); ++i) {
    const Study& study = seed.study(i);
    if (!internal::ShouldAddStudy(study, client_state))
      continue;

    if (internal::IsStudyExpired(study, client_state.reference_date)) {
      expired_studies.push_back(&study);
    } else if (!base::ContainsKey(created_studies, study.name())) {
      ProcessedStudy::ValidateAndAppendStudy(&study, false, filtered_studies);
      created_studies.insert(study.name());
    }
  }

  for (size_t i = 0; i < expired_studies.size(); ++i) {
    if (!base::ContainsKey(created_studies, expired_studies[i]->name())) {
      ProcessedStudy::ValidateAndAppendStudy(expired_studies[i], true,
                                             filtered_studies);
    }
  }
}

}  // namespace variations
