// 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.

#include "extensions/browser/api/declarative/declarative_rule.h"

#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "components/url_matcher/url_matcher_constants.h"
#include "extensions/common/extension_builder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::ParseJson;
using base::test::ParseJsonDeprecated;
using url_matcher::URLMatcher;
using url_matcher::URLMatcherConditionFactory;
using url_matcher::URLMatcherConditionSet;

namespace extensions {

namespace {

std::unique_ptr<base::DictionaryValue> SimpleManifest() {
  return DictionaryBuilder()
      .Set("name", "extension")
      .Set("manifest_version", 2)
      .Set("version", "1.0")
      .Build();
}

}  // namespace

struct RecordingCondition {
  typedef int MatchData;

  URLMatcherConditionFactory* factory;
  std::unique_ptr<base::Value> value;

  void GetURLMatcherConditionSets(
      URLMatcherConditionSet::Vector* condition_sets) const {
    // No condition sets.
  }

  static std::unique_ptr<RecordingCondition> Create(
      const Extension* extension,
      URLMatcherConditionFactory* url_matcher_condition_factory,
      const base::Value& condition,
      std::string* error) {
    const base::DictionaryValue* dict = nullptr;
    if (condition.GetAsDictionary(&dict) && dict->HasKey("bad_key")) {
      *error = "Found error key";
      return nullptr;
    }

    std::unique_ptr<RecordingCondition> result(new RecordingCondition());
    result->factory = url_matcher_condition_factory;
    result->value.reset(condition.DeepCopy());
    return result;
  }
};
typedef DeclarativeConditionSet<RecordingCondition> RecordingConditionSet;

TEST(DeclarativeConditionTest, ErrorConditionSet) {
  URLMatcher matcher;
  RecordingConditionSet::Values conditions;
  conditions.push_back(ParseJsonDeprecated("{\"key\": 1}"));
  conditions.push_back(ParseJsonDeprecated("{\"bad_key\": 2}"));

  std::string error;
  std::unique_ptr<RecordingConditionSet> result = RecordingConditionSet::Create(
      nullptr, matcher.condition_factory(), conditions, &error);
  EXPECT_EQ("Found error key", error);
  ASSERT_FALSE(result);
}

TEST(DeclarativeConditionTest, CreateConditionSet) {
  URLMatcher matcher;
  RecordingConditionSet::Values conditions;
  conditions.push_back(ParseJsonDeprecated("{\"key\": 1}"));
  conditions.push_back(ParseJsonDeprecated("[\"val1\", 2]"));

  // Test insertion
  std::string error;
  std::unique_ptr<RecordingConditionSet> result = RecordingConditionSet::Create(
      nullptr, matcher.condition_factory(), conditions, &error);
  EXPECT_EQ("", error);
  ASSERT_TRUE(result);
  EXPECT_EQ(2u, result->conditions().size());

  EXPECT_EQ(matcher.condition_factory(), result->conditions()[0]->factory);
  EXPECT_TRUE(ParseJsonDeprecated("{\"key\": 1}")
                  ->Equals(result->conditions()[0]->value.get()));
}

struct FulfillableCondition {
  struct MatchData {
    int value;
    const std::set<URLMatcherConditionSet::ID>& url_matches;
  };

  scoped_refptr<URLMatcherConditionSet> condition_set;
  int condition_set_id;
  int max_value;

  URLMatcherConditionSet::ID url_matcher_condition_set_id() const {
    return condition_set_id;
  }

  scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const {
    return condition_set;
  }

  void GetURLMatcherConditionSets(
      URLMatcherConditionSet::Vector* condition_sets) const {
    if (condition_set.get())
      condition_sets->push_back(condition_set);
  }

  bool IsFulfilled(const MatchData& match_data) const {
    if (condition_set_id != -1 &&
        !base::Contains(match_data.url_matches, condition_set_id))
      return false;
    return match_data.value <= max_value;
  }

  static std::unique_ptr<FulfillableCondition> Create(
      const Extension* extension,
      URLMatcherConditionFactory* url_matcher_condition_factory,
      const base::Value& condition,
      std::string* error) {
    std::unique_ptr<FulfillableCondition> result(new FulfillableCondition());
    const base::DictionaryValue* dict;
    if (!condition.GetAsDictionary(&dict)) {
      *error = "Expected dict";
      return result;
    }
    if (!dict->GetInteger("url_id", &result->condition_set_id))
      result->condition_set_id = -1;
    if (!dict->GetInteger("max", &result->max_value))
      *error = "Expected integer at ['max']";
    if (result->condition_set_id != -1) {
      result->condition_set = new URLMatcherConditionSet(
          result->condition_set_id,
          URLMatcherConditionSet::Conditions());
    }
    return result;
  }
};

TEST(DeclarativeConditionTest, FulfillConditionSet) {
  typedef DeclarativeConditionSet<FulfillableCondition> FulfillableConditionSet;
  FulfillableConditionSet::Values conditions;
  conditions.push_back(ParseJsonDeprecated("{\"url_id\": 1, \"max\": 3}"));
  conditions.push_back(ParseJsonDeprecated("{\"url_id\": 2, \"max\": 5}"));
  conditions.push_back(ParseJsonDeprecated("{\"url_id\": 3, \"max\": 1}"));
  conditions.push_back(ParseJsonDeprecated("{\"max\": -5}"));  // No url.

  // Test insertion
  std::string error;
  std::unique_ptr<FulfillableConditionSet> result =
      FulfillableConditionSet::Create(nullptr, nullptr, conditions, &error);
  ASSERT_EQ("", error);
  ASSERT_TRUE(result);
  EXPECT_EQ(4u, result->conditions().size());

  std::set<URLMatcherConditionSet::ID> url_matches;
  FulfillableCondition::MatchData match_data = { 0, url_matches };
  EXPECT_FALSE(result->IsFulfilled(1, match_data))
      << "Testing an ID that's not in url_matches forwards to the Condition, "
      << "which doesn't match.";
  EXPECT_FALSE(result->IsFulfilled(-1, match_data))
      << "Testing the 'no ID' value tries to match the 4th condition, but "
      << "its max is too low.";
  match_data.value = -5;
  EXPECT_TRUE(result->IsFulfilled(-1, match_data))
      << "Testing the 'no ID' value tries to match the 4th condition, and "
      << "this value is low enough.";

  url_matches.insert(1);
  match_data.value = 3;
  EXPECT_TRUE(result->IsFulfilled(1, match_data))
      << "Tests a condition with a url matcher, for a matching value.";
  match_data.value = 4;
  EXPECT_FALSE(result->IsFulfilled(1, match_data))
      << "Tests a condition with a url matcher, for a non-matching value "
      << "that would match a different condition.";
  url_matches.insert(2);
  EXPECT_TRUE(result->IsFulfilled(2, match_data))
      << "Tests with 2 elements in the match set.";

  // Check the condition sets:
  URLMatcherConditionSet::Vector condition_sets;
  result->GetURLMatcherConditionSets(&condition_sets);
  ASSERT_EQ(3U, condition_sets.size());
  EXPECT_EQ(1, condition_sets[0]->id());
  EXPECT_EQ(2, condition_sets[1]->id());
  EXPECT_EQ(3, condition_sets[2]->id());
}

// DeclarativeAction

class SummingAction : public base::RefCounted<SummingAction> {
 public:
  typedef int ApplyInfo;

  SummingAction(int increment, int min_priority)
      : increment_(increment), min_priority_(min_priority) {}

  static scoped_refptr<const SummingAction> Create(
      content::BrowserContext* browser_context,
      const Extension* extension,
      const base::Value& action,
      std::string* error,
      bool* bad_message) {
    int increment = 0;
    int min_priority = 0;
    const base::DictionaryValue* dict = nullptr;
    EXPECT_TRUE(action.GetAsDictionary(&dict));
    if (dict->HasKey("error")) {
      EXPECT_TRUE(dict->GetString("error", error));
      return nullptr;
    }
    if (dict->HasKey("bad")) {
      *bad_message = true;
      return nullptr;
    }

    EXPECT_TRUE(dict->GetInteger("value", &increment));
    dict->GetInteger("priority", &min_priority);
    return scoped_refptr<const SummingAction>(
        new SummingAction(increment, min_priority));
  }

  void Apply(const std::string& extension_id,
             const base::Time& install_time,
             int* sum) const {
    *sum += increment_;
  }

  int increment() const { return increment_; }
  int minimum_priority() const {
    return min_priority_;
  }

 private:
  friend class base::RefCounted<SummingAction>;
  virtual ~SummingAction() {}

  int increment_;
  int min_priority_;
};
typedef DeclarativeActionSet<SummingAction> SummingActionSet;

TEST(DeclarativeActionTest, ErrorActionSet) {
  SummingActionSet::Values actions;
  actions.push_back(ParseJsonDeprecated("{\"value\": 1}"));
  actions.push_back(ParseJsonDeprecated("{\"error\": \"the error\"}"));

  std::string error;
  bool bad = false;
  std::unique_ptr<SummingActionSet> result =
      SummingActionSet::Create(nullptr, nullptr, actions, &error, &bad);
  EXPECT_EQ("the error", error);
  EXPECT_FALSE(bad);
  EXPECT_FALSE(result);

  actions.clear();
  actions.push_back(ParseJsonDeprecated("{\"value\": 1}"));
  actions.push_back(ParseJsonDeprecated("{\"bad\": 3}"));
  result = SummingActionSet::Create(nullptr, nullptr, actions, &error, &bad);
  EXPECT_EQ("", error);
  EXPECT_TRUE(bad);
  EXPECT_FALSE(result);
}

TEST(DeclarativeActionTest, ApplyActionSet) {
  SummingActionSet::Values actions;
  actions.push_back(
      ParseJsonDeprecated("{\"value\": 1,"
                          " \"priority\": 5}"));
  actions.push_back(ParseJsonDeprecated("{\"value\": 2}"));

  // Test insertion
  std::string error;
  bool bad = false;
  std::unique_ptr<SummingActionSet> result =
      SummingActionSet::Create(nullptr, nullptr, actions, &error, &bad);
  EXPECT_EQ("", error);
  EXPECT_FALSE(bad);
  ASSERT_TRUE(result);
  EXPECT_EQ(2u, result->actions().size());

  int sum = 0;
  result->Apply("ext_id", base::Time(), &sum);
  EXPECT_EQ(3, sum);
  EXPECT_EQ(5, result->GetMinimumPriority());
}

TEST(DeclarativeRuleTest, Create) {
  typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
  Rule::JsonRule json_rule;
  ASSERT_TRUE(Rule::JsonRule::Populate(ParseJson(R"(
      {
        "id": "rule1",
        "conditions": [
          {"url_id": 1, "max": 3},
          {"url_id": 2, "max": 5},
        ],
        "actions": [
          {
            "value": 2
          }
        ],
        "priority": 200
      })"),
                                       &json_rule));

  const char kExtensionId[] = "ext1";
  scoped_refptr<const Extension> extension = ExtensionBuilder()
                                                 .SetManifest(SimpleManifest())
                                                 .SetID(kExtensionId)
                                                 .Build();

  base::Time install_time = base::Time::Now();

  URLMatcher matcher;
  std::string error;
  std::unique_ptr<Rule> rule(Rule::Create(
      matcher.condition_factory(), nullptr, extension.get(), install_time,
      json_rule, Rule::ConsistencyChecker(), &error));
  EXPECT_EQ("", error);
  ASSERT_TRUE(rule.get());

  EXPECT_EQ(kExtensionId, rule->id().first);
  EXPECT_EQ("rule1", rule->id().second);

  EXPECT_EQ(200, rule->priority());

  const Rule::ConditionSet& condition_set = rule->conditions();
  const Rule::ConditionSet::Conditions& conditions =
      condition_set.conditions();
  ASSERT_EQ(2u, conditions.size());
  EXPECT_EQ(3, conditions[0]->max_value);
  EXPECT_EQ(5, conditions[1]->max_value);

  const Rule::ActionSet& action_set = rule->actions();
  const Rule::ActionSet::Actions& actions = action_set.actions();
  ASSERT_EQ(1u, actions.size());
  EXPECT_EQ(2, actions[0]->increment());

  int sum = 0;
  rule->Apply(&sum);
  EXPECT_EQ(2, sum);
}

bool AtLeastOneCondition(
    const DeclarativeConditionSet<FulfillableCondition>* conditions,
    const DeclarativeActionSet<SummingAction>* actions,
    std::string* error) {
  if (conditions->conditions().empty()) {
    *error = "No conditions";
    return false;
  }
  return true;
}

TEST(DeclarativeRuleTest, CheckConsistency) {
  typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
  URLMatcher matcher;
  std::string error;
  Rule::JsonRule json_rule;
  const char kExtensionId[] = "ext1";
  scoped_refptr<const Extension> extension = ExtensionBuilder()
                                                 .SetManifest(SimpleManifest())
                                                 .SetID(kExtensionId)
                                                 .Build();

  ASSERT_TRUE(Rule::JsonRule::Populate(ParseJson(R"(
      {
        "id": "rule1",
        "conditions": [
          {"url_id": 1, "max": 3},
          {"url_id": 2, "max": 5},
        ],
        "actions": [
          {
            "value": 2
          }
        ],
        "priority": 200
      })"),
                                       &json_rule));
  std::unique_ptr<Rule> rule(Rule::Create(
      matcher.condition_factory(), nullptr, extension.get(), base::Time(),
      json_rule, base::BindOnce(AtLeastOneCondition), &error));
  EXPECT_TRUE(rule);
  EXPECT_EQ("", error);

  ASSERT_TRUE(Rule::JsonRule::Populate(ParseJson(R"({
                                                   "id": "rule1",
                                                   "conditions": [
                                                   ],
                                                   "actions": [
                                                     {
                                                       "value": 2
                                                     }
                                                   ],
                                                   "priority": 200
                                                 })"),
                                       &json_rule));
  rule = Rule::Create(matcher.condition_factory(), nullptr, extension.get(),
                      base::Time(), json_rule,
                      base::BindOnce(AtLeastOneCondition), &error);
  EXPECT_FALSE(rule);
  EXPECT_EQ("No conditions", error);
}

}  // namespace extensions
