// Copyright 2013 The Chromium Authors
// 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/rules_registry.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/run_loop.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/api/declarative/test_rules_registry.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
const char kExtensionId[] = "foobar";
const char kRuleId[] = "foo";
const int key = extensions::RulesRegistryService::kDefaultRulesRegistryID;
}  // namespace

namespace extensions {

TEST(RulesRegistryTest, FillOptionalIdentifiers) {
  content::BrowserTaskEnvironment task_environment;

  std::string error;
  scoped_refptr<RulesRegistry> registry =
      new TestRulesRegistry("" /*event_name*/, key);

  // Add rules and check that their identifiers are filled and unique.

  {
    std::vector<api::events::Rule> add_rules;
    add_rules.emplace_back();
    add_rules.emplace_back();
    error = registry->AddRules(kExtensionId, std::move(add_rules));
    EXPECT_TRUE(error.empty()) << error;
  }

  std::vector<const api::events::Rule*> get_rules;
  registry->GetAllRules(kExtensionId, &get_rules);

  ASSERT_EQ(2u, get_rules.size());

  ASSERT_TRUE(get_rules[0]->id);
  // Make a copy of the id that this rule was assigned so that we can try to
  // reuse it later when the rule is gone.
  std::string id0 = *get_rules[0]->id;
  EXPECT_NE("", id0);

  ASSERT_TRUE(get_rules[1]->id);
  EXPECT_NE("", *get_rules[1]->id);

  EXPECT_NE(id0, *get_rules[1]->id);

  EXPECT_EQ(1u /*extensions*/ + 2u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  // Check that we cannot add a new rule with the same ID.

  {
    std::vector<api::events::Rule> add_rules;
    add_rules.emplace_back();
    add_rules[0].id = id0;
    error = registry->AddRules(kExtensionId, std::move(add_rules));
    EXPECT_FALSE(error.empty());
  }

  std::vector<const api::events::Rule*> get_rules_2;
  registry->GetAllRules(kExtensionId, &get_rules_2);
  ASSERT_EQ(2u, get_rules_2.size());
  EXPECT_EQ(1u /*extensions*/ + 2u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  // Check that we can register the old rule IDs once they were unregistered.

  std::vector<std::string> remove_rules_3;
  remove_rules_3.push_back(id0);
  error = registry->RemoveRules(kExtensionId, remove_rules_3);
  EXPECT_TRUE(error.empty()) << error;

  EXPECT_EQ(1u /*extensions*/ + 1u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  std::vector<const api::events::Rule*> get_rules_3a;
  registry->GetAllRules(kExtensionId, &get_rules_3a);
  ASSERT_EQ(1u, get_rules_3a.size());

  {
    std::vector<api::events::Rule> add_rules;
    add_rules.emplace_back();
    add_rules[0].id = id0;
    error = registry->AddRules(kExtensionId, std::move(add_rules));
    EXPECT_TRUE(error.empty()) << error;
    EXPECT_EQ(1u /*extensions*/ + 2u /*rules*/,
              registry->GetNumberOfUsedRuleIdentifiersForTesting());
  }

  std::vector<const api::events::Rule*> get_rules_3b;
  registry->GetAllRules(kExtensionId, &get_rules_3b);
  ASSERT_EQ(2u, get_rules_3b.size());

  // Check that we can register a rule with an ID that is not modified.

  error = registry->RemoveAllRules(kExtensionId);
  EXPECT_TRUE(error.empty()) << error;
  EXPECT_EQ(0u /*extensions*/ + 0u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  std::vector<const api::events::Rule*> get_rules_4a;
  registry->GetAllRules(kExtensionId, &get_rules_4a);
  ASSERT_TRUE(get_rules_4a.empty());

  {
    std::vector<api::events::Rule> add_rules;
    add_rules.emplace_back();
    add_rules[0].id = kRuleId;
    error = registry->AddRules(kExtensionId, std::move(add_rules));
    EXPECT_TRUE(error.empty()) << error;
  }

  EXPECT_EQ(1u /*extensions*/ + 1u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  std::vector<const api::events::Rule*> get_rules_4b;
  registry->GetAllRules(kExtensionId, &get_rules_4b);

  ASSERT_EQ(1u, get_rules_4b.size());

  ASSERT_TRUE(get_rules_4b[0]->id);
  EXPECT_EQ(kRuleId, *get_rules_4b[0]->id);

  // Create extension
  scoped_refptr<const Extension> extension =
      ExtensionBuilder("Test").SetID(kExtensionId).Build();
  registry->OnExtensionUninstalled(extension.get());
  EXPECT_EQ(0u /*extensions*/ + 0u /*rules*/,
            registry->GetNumberOfUsedRuleIdentifiersForTesting());

  // Make sure that deletion traits of registry are executed.
  registry.reset();
  base::RunLoop().RunUntilIdle();
}

TEST(RulesRegistryTest, FillOptionalPriority) {
  content::BrowserTaskEnvironment task_environment;

  std::string error;
  scoped_refptr<RulesRegistry> registry =
      new TestRulesRegistry("" /*event_name*/, key);

  // Add rules and check that their priorities are filled if they are empty.

  {
    std::vector<api::events::Rule> add_rules;
    add_rules.emplace_back();
    add_rules[0].priority = 2;
    add_rules.emplace_back();
    error = registry->AddRules(kExtensionId, std::move(add_rules));
    EXPECT_TRUE(error.empty()) << error;
  }

  std::vector<const api::events::Rule*> get_rules;
  registry->GetAllRules(kExtensionId, &get_rules);

  ASSERT_EQ(2u, get_rules.size());

  ASSERT_TRUE(get_rules[0]->priority);
  ASSERT_TRUE(get_rules[1]->priority);

  // Verify the precondition so that the following EXPECT_EQ statements work.
  EXPECT_GT(RulesRegistry::DEFAULT_PRIORITY, 2);
  EXPECT_EQ(2, std::min(*get_rules[0]->priority, *get_rules[1]->priority));
  EXPECT_EQ(RulesRegistry::DEFAULT_PRIORITY,
            std::max(*get_rules[0]->priority, *get_rules[1]->priority));

  // Make sure that deletion traits of registry are executed.
  registry.reset();
  base::RunLoop().RunUntilIdle();
}

// Test verifies 2 rules defined in the manifest appear in the registry.
TEST(RulesRegistryTest, TwoRulesInManifest) {
  content::BrowserTaskEnvironment task_environment;

  // Create extension
  base::Value::Dict manifest = base::test::ParseJsonDict(
      "{"
      "  \"name\": \"Test\","
      "  \"version\": \"1\","
      "  \"manifest_version\": 2,"
      "  \"event_rules\": ["
      "    {"
      "      \"id\": \"000\","
      "      \"priority\": 200,"
      "      \"tags\": [\"tagged\"],"
      "      \"event\": \"declarativeContent.onPageChanged\","
      "      \"actions\": [{"
      "        \"type\": \"declarativeContent.ShowAction\""
      "      }],"
      "      \"conditions\" : [{"
      "        \"css\": [\"video\"],"
      "        \"type\" : \"declarativeContent.PageStateMatcher\""
      "      }]"
      "    },"
      "    {"
      "      \"event\": \"declarativeContent.onPageChanged\","
      "      \"actions\": [{"
      "        \"type\": \"declarativeContent.ShowAction\""
      "      }],"
      "      \"conditions\" : [{"
      "        \"css\": [\"input[type='password']\"],"
      "        \"type\" : \"declarativeContent.PageStateMatcher\""
      "      }]"
      "    }"
      "  ]"
      "}");
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(std::move(manifest))
          .SetID(kExtensionId)
          .Build();

  scoped_refptr<RulesRegistry> registry =
      new TestRulesRegistry("declarativeContent.onPageChanged", key);
  // Simulate what RulesRegistryService would do on extension load.
  registry->OnExtensionLoaded(extension.get());

  std::vector<const api::events::Rule*> get_rules;
  registry->GetAllRules(kExtensionId, &get_rules);

  ASSERT_EQ(2u, get_rules.size());
  base::Value::Dict expected_rule_0 = base::test::ParseJsonDict(
      "{"
      "  \"id\": \"000\","
      "  \"priority\": 200,"
      "  \"tags\": [\"tagged\"],"
      "  \"actions\": [{"
      "    \"instanceType\": \"declarativeContent.ShowAction\""
      "  }],"
      "  \"conditions\" : [{"
      "    \"css\": [\"video\"],"
      "    \"instanceType\" : \"declarativeContent.PageStateMatcher\""
      "  }]"
      "}");
  EXPECT_EQ(expected_rule_0, get_rules[0]->ToValue());

  base::Value::Dict expected_rule_1 = base::test::ParseJsonDict(
      "{"
      "  \"id\": \"_0_\","
      "  \"priority\": 100,"
      "  \"actions\": [{"
      "    \"instanceType\": \"declarativeContent.ShowAction\""
      "  }],"
      "  \"conditions\" : [{"
      "    \"css\": [\"input[type='password']\"],"
      "    \"instanceType\" : \"declarativeContent.PageStateMatcher\""
      "  }]"
      "}");
  EXPECT_EQ(expected_rule_1, get_rules[1]->ToValue());
}

// Tests verifies that rules defined in the manifest cannot be deleted but
// programmatically added rules still can be deleted.
TEST(RulesRegistryTest, DeleteRuleInManifest) {
  content::BrowserTaskEnvironment task_environment;

  // Create extension
  base::Value::Dict manifest = base::test::ParseJsonDict(
      "{"
      "  \"name\": \"Test\","
      "  \"version\": \"1\","
      "  \"manifest_version\": 2,"
      "  \"event_rules\": [{"
      "    \"id\":  \"manifest_rule_0\","
      "    \"event\": \"declarativeContent.onPageChanged\","
      "    \"actions\": [{"
      "      \"type\": \"declarativeContent.ShowAction\""
      "    }],"
      "    \"conditions\" : [{"
      "      \"css\": [\"video\"],"
      "      \"type\" : \"declarativeContent.PageStateMatcher\""
      "    }]"
      "  }]"
      "}");
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(std::move(manifest))
          .SetID(kExtensionId)
          .Build();

  scoped_refptr<RulesRegistry> registry =
      new TestRulesRegistry("declarativeContent.onPageChanged", key);
  // Simulate what RulesRegistryService would do on extension load.
  registry->OnExtensionLoaded(extension.get());

  {
    // Add some extra rules outside of the manifest.
    std::vector<api::events::Rule> add_rules;
    api::events::Rule rule_1;
    rule_1.id = "rule_1";
    api::events::Rule rule_2;
    rule_2.id = "rule_2";
    add_rules.push_back(std::move(rule_1));
    add_rules.push_back(std::move(rule_2));
    registry->AddRules(kExtensionId, std::move(add_rules));
  }

  std::vector<const api::events::Rule*> get_rules;
  registry->GetAllRules(kExtensionId, &get_rules);
  ASSERT_EQ(3u, get_rules.size());
  EXPECT_EQ("manifest_rule_0", *(get_rules[0]->id));
  EXPECT_EQ("rule_1", *(get_rules[1]->id));
  EXPECT_EQ("rule_2", *(get_rules[2]->id));

  // Remove a rule from outside the manifest.
  std::vector<std::string> remove_ids;
  remove_ids.push_back("rule_1");
  EXPECT_TRUE(registry->RemoveRules(kExtensionId, remove_ids).empty());
  get_rules.clear();
  registry->GetAllRules(kExtensionId, &get_rules);
  EXPECT_EQ(2u, get_rules.size());
  EXPECT_EQ("manifest_rule_0", *(get_rules[0]->id));
  EXPECT_EQ("rule_2", *(get_rules[1]->id));

  // Attempt to remove rule in manifest.
  remove_ids.clear();
  remove_ids.push_back("manifest_rule_0");
  EXPECT_FALSE(registry->RemoveRules(kExtensionId, remove_ids).empty());
  get_rules.clear();
  registry->GetAllRules(kExtensionId, &get_rules);
  ASSERT_EQ(2u, get_rules.size());
  EXPECT_EQ("manifest_rule_0", *(get_rules[0]->id));
  EXPECT_EQ("rule_2", *(get_rules[1]->id));

  // Remove all rules.
  registry->RemoveAllRules(kExtensionId);
  get_rules.clear();
  registry->GetAllRules(kExtensionId, &get_rules);
  ASSERT_EQ(1u, get_rules.size());
  EXPECT_EQ("manifest_rule_0", *(get_rules[0]->id));
}

}  // namespace extensions
