// Copyright (c) 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.
//
// DeclarativeRule<>, DeclarativeConditionSet<>, and DeclarativeActionSet<>
// templates usable with multiple different declarativeFoo systems.  These are
// templated on the Condition and Action types that define the behavior of a
// particular declarative event.

#ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__
#define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__

#include <limits>
#include <set>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "chrome/common/extensions/api/events.h"
#include "extensions/common/matcher/url_matcher.h"

namespace base {
class Time;
class Value;
}

namespace extensions {

// This class stores a set of conditions that may be part of a DeclarativeRule.
// If any condition is fulfilled, the Actions of the DeclarativeRule can be
// triggered.
//
// ConditionT should be immutable after creation.  It must define the following
// members:
//
//   // Arguments passed through from DeclarativeConditionSet::Create.
//   static scoped_ptr<ConditionT> Create(
//       URLMatcherConditionFactory* url_matcher_condition_factory,
//       // Except this argument gets elements of the AnyVector.
//       const base::Value& definition,
//       std::string* error);
//   // If the Condition needs to be filtered by some URLMatcherConditionSets,
//   // append them to |condition_sets|.
//   // DeclarativeConditionSet::GetURLMatcherConditionSets forwards here.
//   void GetURLMatcherConditionSets(
//       URLMatcherConditionSet::Vector* condition_sets);
//   // |match_data| passed through from DeclarativeConditionSet::IsFulfilled.
//   bool IsFulfilled(const ConditionT::MatchData& match_data);
template<typename ConditionT>
class DeclarativeConditionSet {
 public:
  typedef std::vector<linked_ptr<base::Value> > AnyVector;
  typedef std::vector<linked_ptr<const ConditionT> > Conditions;
  typedef typename Conditions::const_iterator const_iterator;

  // Factory method that creates a DeclarativeConditionSet according to the JSON
  // array |conditions| passed by the extension API. Sets |error| and returns
  // NULL in case of an error.
  static scoped_ptr<DeclarativeConditionSet> Create(
      URLMatcherConditionFactory* url_matcher_condition_factory,
      const AnyVector& conditions,
      std::string* error);

  const Conditions& conditions() const {
    return conditions_;
  }

  const_iterator begin() const { return conditions_.begin(); }
  const_iterator end() const { return conditions_.end(); }

  // If |url_match_trigger| is not -1, this function looks for a condition
  // with this URLMatcherConditionSet, and forwards to that condition's
  // IsFulfilled(|match_data|). If there is no such condition, then false is
  // returned. If |url_match_trigger| is -1, this function returns whether any
  // of the conditions without URL attributes is satisfied.
  bool IsFulfilled(URLMatcherConditionSet::ID url_match_trigger,
                   const typename ConditionT::MatchData& match_data) const;

  // Appends the URLMatcherConditionSet from all conditions to |condition_sets|.
  void GetURLMatcherConditionSets(
      URLMatcherConditionSet::Vector* condition_sets) const;

  // Returns whether there are some conditions without UrlFilter attributes.
  bool HasConditionsWithoutUrls() const {
    return !conditions_without_urls_.empty();
  }

 private:
  typedef std::map<URLMatcherConditionSet::ID, const ConditionT*>
      URLMatcherIdToCondition;

  DeclarativeConditionSet(
      const Conditions& conditions,
      const URLMatcherIdToCondition& match_id_to_condition,
      const std::vector<const ConditionT*>& conditions_without_urls);

  const URLMatcherIdToCondition match_id_to_condition_;
  const Conditions conditions_;
  const std::vector<const ConditionT*> conditions_without_urls_;

  DISALLOW_COPY_AND_ASSIGN(DeclarativeConditionSet);
};

// Immutable container for multiple actions.
//
// ActionT should be immutable after creation.  It must define the following
// members:
//
//   // Arguments passed through from ActionSet::Create.
//   static scoped_ptr<ActionT> Create(
//       // Except this argument gets elements of the AnyVector.
//       const base::Value& definition,
//       std::string* error, bool* bad_message);
//   void Apply(const std::string& extension_id,
//              const base::Time& extension_install_time,
//              // Contains action-type-specific in/out parameters.
//              typename ActionT::ApplyInfo* apply_info) const;
//   // Only needed if the RulesRegistry calls DeclarativeActionSet::Revert().
//   void Revert(const std::string& extension_id,
//               const base::Time& extension_install_time,
//               // Contains action-type-specific in/out parameters.
//               typename ActionT::ApplyInfo* apply_info) const;
//   // Return the minimum priority of rules that can be evaluated after this
//   // action runs.  A suitable default value is MIN_INT.
//   int minimum_priority() const;
//
// TODO(battre): As DeclarativeActionSet can become the single owner of all
// actions, we can optimize here by making some of them singletons (e.g. Cancel
// actions).
template<typename ActionT>
class DeclarativeActionSet {
 public:
  typedef std::vector<linked_ptr<base::Value> > AnyVector;
  typedef std::vector<scoped_refptr<const ActionT> > Actions;

  explicit DeclarativeActionSet(const Actions& actions);

  // Factory method that instantiates a DeclarativeActionSet according to
  // |actions| which represents the array of actions received from the
  // extension API.
  static scoped_ptr<DeclarativeActionSet> Create(const AnyVector& actions,
                                                 std::string* error,
                                                 bool* bad_message);

  // Rules call this method when their conditions are fulfilled.
  void Apply(const std::string& extension_id,
             const base::Time& extension_install_time,
             typename ActionT::ApplyInfo* apply_info) const;

  // Rules call this method when they have stateful conditions, and those
  // conditions stop being fulfilled.  Rules with event-based conditions (e.g. a
  // network request happened) will never Revert() an action.
  void Revert(const std::string& extension_id,
              const base::Time& extension_install_time,
              typename ActionT::ApplyInfo* apply_info) const;

  // Returns the minimum priority of rules that may be evaluated after
  // this rule. Defaults to MIN_INT.
  int GetMinimumPriority() const;

  const Actions& actions() const { return actions_; }

 private:
  const Actions actions_;

  DISALLOW_COPY_AND_ASSIGN(DeclarativeActionSet);
};

// Representation of a rule of a declarative API:
// https://developer.chrome.com/beta/extensions/events.html#declarative.
// Generally a RulesRegistry will hold a collection of Rules for a given
// declarative API and contain the logic for matching and applying them.
//
// See DeclarativeConditionSet and DeclarativeActionSet for the requirements on
// ConditionT and ActionT.
template<typename ConditionT, typename ActionT>
class DeclarativeRule {
 public:
  typedef std::string ExtensionId;
  typedef std::string RuleId;
  typedef std::pair<ExtensionId, RuleId> GlobalRuleId;
  typedef int Priority;
  typedef DeclarativeConditionSet<ConditionT> ConditionSet;
  typedef DeclarativeActionSet<ActionT> ActionSet;
  typedef extensions::api::events::Rule JsonRule;
  typedef std::vector<std::string> Tags;

  // Checks whether the set of |conditions| and |actions| are consistent.
  // Returns true in case of consistency and MUST set |error| otherwise.
  typedef base::Callback<bool(const ConditionSet* conditions,
                              const ActionSet* actions,
                              std::string* error)> ConsistencyChecker;

  DeclarativeRule(const GlobalRuleId& id,
                  const Tags& tags,
                  base::Time extension_installation_time,
                  scoped_ptr<ConditionSet> conditions,
                  scoped_ptr<ActionSet> actions,
                  Priority priority);

  // Creates a DeclarativeRule for an extension given a json definition.  The
  // format of each condition and action's json is up to the specific ConditionT
  // and ActionT.
  //
  // Before constructing the final rule, calls check_consistency(conditions,
  // actions, error) and returns NULL if it fails.  Pass NULL if no consistency
  // check is needed.  If |error| is empty, the translation was successful and
  // the returned rule is internally consistent.
  static scoped_ptr<DeclarativeRule> Create(
      URLMatcherConditionFactory* url_matcher_condition_factory,
      const std::string& extension_id,
      base::Time extension_installation_time,
      linked_ptr<JsonRule> rule,
      ConsistencyChecker check_consistency,
      std::string* error);

  const GlobalRuleId& id() const { return id_; }
  const Tags& tags() const { return tags_; }
  const std::string& extension_id() const { return id_.first; }
  const ConditionSet& conditions() const { return *conditions_; }
  const ActionSet& actions() const { return *actions_; }
  Priority priority() const { return priority_; }

  // Calls actions().Apply(extension_id(), extension_installation_time_,
  // apply_info). This function should only be called when the conditions_ are
  // fulfilled (from a semantic point of view; no harm is done if this function
  // is called at other times for testing purposes).
  void Apply(typename ActionT::ApplyInfo* apply_info) const;

  // Returns the minimum priority of rules that may be evaluated after
  // this rule. Defaults to MIN_INT. Only valid if the conditions of this rule
  // are fulfilled.
  Priority GetMinimumPriority() const;

 private:
  GlobalRuleId id_;
  Tags tags_;
  base::Time extension_installation_time_;  // For precedences of rules.
  scoped_ptr<ConditionSet> conditions_;
  scoped_ptr<ActionSet> actions_;
  Priority priority_;

  DISALLOW_COPY_AND_ASSIGN(DeclarativeRule);
};

// Implementation details below here.

//
// DeclarativeConditionSet
//

template<typename ConditionT>
bool DeclarativeConditionSet<ConditionT>::IsFulfilled(
    URLMatcherConditionSet::ID url_match_trigger,
    const typename ConditionT::MatchData& match_data) const {
  if (url_match_trigger == -1) {
    // Invalid trigger -- indication that we should only check conditions
    // without URL attributes.
    for (typename std::vector<const ConditionT*>::const_iterator it =
             conditions_without_urls_.begin();
         it != conditions_without_urls_.end(); ++it) {
      if ((*it)->IsFulfilled(match_data))
        return true;
    }
    return false;
  }

  typename URLMatcherIdToCondition::const_iterator triggered =
      match_id_to_condition_.find(url_match_trigger);
  return (triggered != match_id_to_condition_.end() &&
          triggered->second->IsFulfilled(match_data));
}

template<typename ConditionT>
void DeclarativeConditionSet<ConditionT>::GetURLMatcherConditionSets(
    URLMatcherConditionSet::Vector* condition_sets) const {
  for (typename Conditions::const_iterator i = conditions_.begin();
       i != conditions_.end(); ++i) {
    (*i)->GetURLMatcherConditionSets(condition_sets);
  }
}

// static
template<typename ConditionT>
scoped_ptr<DeclarativeConditionSet<ConditionT> >
DeclarativeConditionSet<ConditionT>::Create(
    URLMatcherConditionFactory* url_matcher_condition_factory,
    const AnyVector& conditions,
    std::string* error) {
  Conditions result;

  for (AnyVector::const_iterator i = conditions.begin();
       i != conditions.end(); ++i) {
    CHECK(i->get());
    scoped_ptr<ConditionT> condition =
        ConditionT::Create(url_matcher_condition_factory, **i, error);
    if (!error->empty())
      return scoped_ptr<DeclarativeConditionSet>();
    result.push_back(make_linked_ptr(condition.release()));
  }

  URLMatcherIdToCondition match_id_to_condition;
  std::vector<const ConditionT*> conditions_without_urls;
  URLMatcherConditionSet::Vector condition_sets;

  for (typename Conditions::const_iterator i = result.begin();
       i != result.end(); ++i) {
    condition_sets.clear();
    (*i)->GetURLMatcherConditionSets(&condition_sets);
    if (condition_sets.empty()) {
      conditions_without_urls.push_back(i->get());
    } else {
      for (URLMatcherConditionSet::Vector::const_iterator
               match_set = condition_sets.begin();
           match_set != condition_sets.end(); ++match_set)
        match_id_to_condition[(*match_set)->id()] = i->get();
    }
  }

  return make_scoped_ptr(new DeclarativeConditionSet(
      result, match_id_to_condition, conditions_without_urls));
}

template<typename ConditionT>
DeclarativeConditionSet<ConditionT>::DeclarativeConditionSet(
    const Conditions& conditions,
    const URLMatcherIdToCondition& match_id_to_condition,
    const std::vector<const ConditionT*>& conditions_without_urls)
    : match_id_to_condition_(match_id_to_condition),
      conditions_(conditions),
      conditions_without_urls_(conditions_without_urls) {}

//
// DeclarativeActionSet
//

template<typename ActionT>
DeclarativeActionSet<ActionT>::DeclarativeActionSet(const Actions& actions)
    : actions_(actions) {}

// static
template<typename ActionT>
scoped_ptr<DeclarativeActionSet<ActionT> >
DeclarativeActionSet<ActionT>::Create(
    const AnyVector& actions,
    std::string* error,
    bool* bad_message) {
  *error = "";
  *bad_message = false;
  Actions result;

  for (AnyVector::const_iterator i = actions.begin();
       i != actions.end(); ++i) {
    CHECK(i->get());
    scoped_refptr<const ActionT> action =
        ActionT::Create(**i, error, bad_message);
    if (!error->empty() || *bad_message)
      return scoped_ptr<DeclarativeActionSet>();
    result.push_back(action);
  }

  return scoped_ptr<DeclarativeActionSet>(new DeclarativeActionSet(result));
}

template<typename ActionT>
void DeclarativeActionSet<ActionT>::Apply(
    const std::string& extension_id,
    const base::Time& extension_install_time,
    typename ActionT::ApplyInfo* apply_info) const {
  for (typename Actions::const_iterator i = actions_.begin();
       i != actions_.end(); ++i)
    (*i)->Apply(extension_id, extension_install_time, apply_info);
}

template<typename ActionT>
void DeclarativeActionSet<ActionT>::Revert(
    const std::string& extension_id,
    const base::Time& extension_install_time,
    typename ActionT::ApplyInfo* apply_info) const {
  for (typename Actions::const_iterator i = actions_.begin();
       i != actions_.end(); ++i)
    (*i)->Revert(extension_id, extension_install_time, apply_info);
}

template<typename ActionT>
int DeclarativeActionSet<ActionT>::GetMinimumPriority() const {
  int minimum_priority = std::numeric_limits<int>::min();
  for (typename Actions::const_iterator i = actions_.begin();
       i != actions_.end(); ++i) {
    minimum_priority = std::max(minimum_priority, (*i)->minimum_priority());
  }
  return minimum_priority;
}

//
// DeclarativeRule
//

template<typename ConditionT, typename ActionT>
DeclarativeRule<ConditionT, ActionT>::DeclarativeRule(
    const GlobalRuleId& id,
    const Tags& tags,
    base::Time extension_installation_time,
    scoped_ptr<ConditionSet> conditions,
    scoped_ptr<ActionSet> actions,
    Priority priority)
    : id_(id),
      tags_(tags),
      extension_installation_time_(extension_installation_time),
      conditions_(conditions.release()),
      actions_(actions.release()),
      priority_(priority) {
  CHECK(conditions_.get());
  CHECK(actions_.get());
}

// static
template<typename ConditionT, typename ActionT>
scoped_ptr<DeclarativeRule<ConditionT, ActionT> >
DeclarativeRule<ConditionT, ActionT>::Create(
    URLMatcherConditionFactory* url_matcher_condition_factory,
    const std::string& extension_id,
    base::Time extension_installation_time,
    linked_ptr<JsonRule> rule,
    ConsistencyChecker check_consistency,
    std::string* error) {
  scoped_ptr<DeclarativeRule> error_result;

  scoped_ptr<ConditionSet> conditions = ConditionSet::Create(
      url_matcher_condition_factory, rule->conditions, error);
  if (!error->empty())
    return error_result.Pass();
  CHECK(conditions.get());

  bool bad_message = false;
  scoped_ptr<ActionSet> actions =
      ActionSet::Create(rule->actions, error, &bad_message);
  if (bad_message) {
    // TODO(battre) Export concept of bad_message to caller, the extension
    // should be killed in case it is true.
    *error = "An action of a rule set had an invalid "
        "structure that should have been caught by the JSON validator.";
    return error_result.Pass();
  }
  if (!error->empty() || bad_message)
    return error_result.Pass();
  CHECK(actions.get());

  if (!check_consistency.is_null() &&
      !check_consistency.Run(conditions.get(), actions.get(), error)) {
    DCHECK(!error->empty());
    return error_result.Pass();
  }

  CHECK(rule->priority.get());
  int priority = *(rule->priority);

  GlobalRuleId rule_id(extension_id, *(rule->id));
  Tags tags = rule->tags ? *rule->tags : Tags();
  return scoped_ptr<DeclarativeRule>(
      new DeclarativeRule(rule_id, tags, extension_installation_time,
                          conditions.Pass(), actions.Pass(), priority));
}

template<typename ConditionT, typename ActionT>
void DeclarativeRule<ConditionT, ActionT>::Apply(
    typename ActionT::ApplyInfo* apply_info) const {
  return actions_->Apply(extension_id(),
                         extension_installation_time_,
                         apply_info);
}

template<typename ConditionT, typename ActionT>
int DeclarativeRule<ConditionT, ActionT>::GetMinimumPriority() const {
  return actions_->GetMinimumPriority();
}

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__
