// 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 "extensions/browser/extension_registry.h"

#include <string>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/browser/unloaded_extension_reason.h"
#include "extensions/common/extension_builder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {
namespace {

typedef testing::Test ExtensionRegistryTest;

testing::AssertionResult HasSingleExtension(
    const ExtensionList& list,
    const scoped_refptr<const Extension>& extension) {
  if (list.empty())
    return testing::AssertionFailure() << "No extensions in list";
  if (list.size() > 1) {
    return testing::AssertionFailure() << list.size()
                                       << " extensions, expected 1";
  }
  const Extension* did_load = list[0].get();
  if (did_load != extension.get()) {
    return testing::AssertionFailure() << "Expected " << extension->id()
                                       << " found " << did_load->id();
  }
  return testing::AssertionSuccess();
}

class TestObserver : public ExtensionRegistryObserver {
 public:
  TestObserver() {}

  void Reset() {
    loaded_.clear();
    unloaded_.clear();
    installed_.clear();
    uninstalled_.clear();
  }

  const ExtensionList& loaded() { return loaded_; }
  const ExtensionList& unloaded() { return unloaded_; }
  const ExtensionList& installed() { return installed_; }
  const ExtensionList& uninstalled() { return uninstalled_; }

 private:
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override {
    loaded_.push_back(extension);
  }

  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override {
    unloaded_.push_back(extension);
  }

  void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
                                  const Extension* extension,
                                  bool is_update,
                                  const std::string& old_name) override {
    installed_.push_back(extension);
  }

  void OnExtensionUninstalled(content::BrowserContext* browser_context,
                              const Extension* extension,
                              UninstallReason reason) override {
    uninstalled_.push_back(extension);
  }

  void OnShutdown(ExtensionRegistry* registry) override { Reset(); }

  ExtensionList loaded_;
  ExtensionList unloaded_;
  ExtensionList installed_;
  ExtensionList uninstalled_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

TEST_F(ExtensionRegistryTest, FillAndClearRegistry) {
  ExtensionRegistry registry(NULL);
  scoped_refptr<const Extension> extension1 = ExtensionBuilder("one").Build();
  scoped_refptr<const Extension> extension2 = ExtensionBuilder("two").Build();
  scoped_refptr<const Extension> extension3 = ExtensionBuilder("three").Build();
  scoped_refptr<const Extension> extension4 = ExtensionBuilder("four").Build();

  // All the sets start empty.
  EXPECT_EQ(0u, registry.enabled_extensions().size());
  EXPECT_EQ(0u, registry.disabled_extensions().size());
  EXPECT_EQ(0u, registry.terminated_extensions().size());
  EXPECT_EQ(0u, registry.blocklisted_extensions().size());

  // Extensions can be added to each set.
  registry.AddEnabled(extension1);
  registry.AddDisabled(extension2);
  registry.AddTerminated(extension3);
  registry.AddBlocklisted(extension4);

  EXPECT_EQ(1u, registry.enabled_extensions().size());
  EXPECT_EQ(1u, registry.disabled_extensions().size());
  EXPECT_EQ(1u, registry.terminated_extensions().size());
  EXPECT_EQ(1u, registry.blocklisted_extensions().size());

  // Clearing the registry clears all sets.
  registry.ClearAll();

  EXPECT_EQ(0u, registry.enabled_extensions().size());
  EXPECT_EQ(0u, registry.disabled_extensions().size());
  EXPECT_EQ(0u, registry.terminated_extensions().size());
  EXPECT_EQ(0u, registry.blocklisted_extensions().size());
}

// A simple test of adding and removing things from sets.
TEST_F(ExtensionRegistryTest, AddAndRemoveExtensionFromRegistry) {
  ExtensionRegistry registry(NULL);

  // Adding an extension works.
  scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build();
  EXPECT_TRUE(registry.AddEnabled(extension));
  EXPECT_EQ(1u, registry.enabled_extensions().size());

  // The extension was only added to one set.
  EXPECT_EQ(0u, registry.disabled_extensions().size());
  EXPECT_EQ(0u, registry.terminated_extensions().size());
  EXPECT_EQ(0u, registry.blocklisted_extensions().size());

  // Removing an extension works.
  EXPECT_TRUE(registry.RemoveEnabled(extension->id()));
  EXPECT_EQ(0u, registry.enabled_extensions().size());

  // Trying to remove an extension that isn't in the set fails cleanly.
  EXPECT_FALSE(registry.RemoveEnabled(extension->id()));
}

TEST_F(ExtensionRegistryTest, AddExtensionToRegistryTwice) {
  ExtensionRegistry registry(NULL);
  scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build();

  // An extension can exist in two sets at once. It would be nice to eliminate
  // this functionality, but some users of ExtensionRegistry need it.
  EXPECT_TRUE(registry.AddEnabled(extension));
  EXPECT_TRUE(registry.AddDisabled(extension));

  EXPECT_EQ(1u, registry.enabled_extensions().size());
  EXPECT_EQ(1u, registry.disabled_extensions().size());
  EXPECT_EQ(0u, registry.terminated_extensions().size());
  EXPECT_EQ(0u, registry.blocklisted_extensions().size());
}

TEST_F(ExtensionRegistryTest, GetExtensionById) {
  ExtensionRegistry registry(NULL);

  // Trying to get an extension fails cleanly when the sets are empty.
  EXPECT_FALSE(
      registry.GetExtensionById("id", ExtensionRegistry::EVERYTHING));

  scoped_refptr<const Extension> enabled = ExtensionBuilder("enabled").Build();
  scoped_refptr<const Extension> disabled =
      ExtensionBuilder("disabled").Build();
  scoped_refptr<const Extension> terminated =
      ExtensionBuilder("terminated").Build();
  scoped_refptr<const Extension> blocklisted =
      ExtensionBuilder("blacklisted").Build();

  // Add an extension to each set.
  registry.AddEnabled(enabled);
  registry.AddDisabled(disabled);
  registry.AddTerminated(terminated);
  registry.AddBlocklisted(blocklisted);

  // Enabled is part of everything and the enabled list.
  EXPECT_TRUE(
      registry.GetExtensionById(enabled->id(), ExtensionRegistry::EVERYTHING));
  EXPECT_TRUE(
      registry.GetExtensionById(enabled->id(), ExtensionRegistry::ENABLED));
  EXPECT_FALSE(
      registry.GetExtensionById(enabled->id(), ExtensionRegistry::DISABLED));
  EXPECT_FALSE(
      registry.GetExtensionById(enabled->id(), ExtensionRegistry::TERMINATED));
  EXPECT_FALSE(
      registry.GetExtensionById(enabled->id(), ExtensionRegistry::BLOCKLISTED));

  // Disabled is part of everything and the disabled list.
  EXPECT_TRUE(
      registry.GetExtensionById(disabled->id(), ExtensionRegistry::EVERYTHING));
  EXPECT_FALSE(
      registry.GetExtensionById(disabled->id(), ExtensionRegistry::ENABLED));
  EXPECT_TRUE(
      registry.GetExtensionById(disabled->id(), ExtensionRegistry::DISABLED));
  EXPECT_FALSE(
      registry.GetExtensionById(disabled->id(), ExtensionRegistry::TERMINATED));
  EXPECT_FALSE(registry.GetExtensionById(disabled->id(),
                                         ExtensionRegistry::BLOCKLISTED));

  // Terminated is part of everything and the terminated list.
  EXPECT_TRUE(registry.GetExtensionById(terminated->id(),
                                        ExtensionRegistry::EVERYTHING));
  EXPECT_FALSE(
      registry.GetExtensionById(terminated->id(), ExtensionRegistry::ENABLED));
  EXPECT_FALSE(
      registry.GetExtensionById(terminated->id(), ExtensionRegistry::DISABLED));
  EXPECT_TRUE(registry.GetExtensionById(terminated->id(),
                                        ExtensionRegistry::TERMINATED));
  EXPECT_FALSE(registry.GetExtensionById(terminated->id(),
                                         ExtensionRegistry::BLOCKLISTED));

  // Blocklisted is part of everything and the blocklisted list.
  EXPECT_TRUE(registry.GetExtensionById(blocklisted->id(),
                                        ExtensionRegistry::EVERYTHING));
  EXPECT_FALSE(
      registry.GetExtensionById(blocklisted->id(), ExtensionRegistry::ENABLED));
  EXPECT_FALSE(registry.GetExtensionById(blocklisted->id(),
                                         ExtensionRegistry::DISABLED));
  EXPECT_FALSE(registry.GetExtensionById(blocklisted->id(),
                                         ExtensionRegistry::TERMINATED));
  EXPECT_TRUE(registry.GetExtensionById(blocklisted->id(),
                                        ExtensionRegistry::BLOCKLISTED));

  // Enabled can be found with multiple flags set.
  EXPECT_TRUE(registry.GetExtensionById(
      enabled->id(),
      ExtensionRegistry::ENABLED | ExtensionRegistry::TERMINATED));

  // Enabled isn't found if the wrong flags are set.
  EXPECT_FALSE(registry.GetExtensionById(
      enabled->id(),
      ExtensionRegistry::DISABLED | ExtensionRegistry::BLOCKLISTED));
}

TEST_F(ExtensionRegistryTest, Observer) {
  ExtensionRegistry registry(NULL);
  TestObserver observer;
  registry.AddObserver(&observer);

  EXPECT_TRUE(observer.loaded().empty());
  EXPECT_TRUE(observer.unloaded().empty());
  EXPECT_TRUE(observer.installed().empty());

  scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build();

  registry.TriggerOnWillBeInstalled(extension.get(), false, std::string());
  EXPECT_TRUE(HasSingleExtension(observer.installed(), extension.get()));

  registry.AddEnabled(extension);
  registry.TriggerOnLoaded(extension.get());

  registry.TriggerOnWillBeInstalled(extension.get(), true, "foo");

  EXPECT_TRUE(HasSingleExtension(observer.loaded(), extension.get()));
  EXPECT_TRUE(observer.unloaded().empty());
  registry.Shutdown();

  registry.RemoveEnabled(extension->id());
  registry.TriggerOnUnloaded(extension.get(), UnloadedExtensionReason::DISABLE);

  EXPECT_TRUE(observer.loaded().empty());
  EXPECT_TRUE(HasSingleExtension(observer.unloaded(), extension.get()));
  registry.Shutdown();

  registry.TriggerOnUninstalled(extension.get(), UNINSTALL_REASON_FOR_TESTING);
  EXPECT_TRUE(observer.installed().empty());
  EXPECT_TRUE(HasSingleExtension(observer.uninstalled(), extension.get()));

  registry.RemoveObserver(&observer);
}

// Regression test for https://crbug.com/724563.
TEST_F(ExtensionRegistryTest, TerminatedExtensionStoredVersion) {
  const std::string kVersionString = "1.2.3.4";
  ExtensionRegistry registry(nullptr);
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(DictionaryBuilder()
                           .Set("name", "Test")
                           .Set("version", kVersionString)
                           .Set("manifest_version", 2)
                           .Build())
          .Build();
  const ExtensionId extension_id = extension->id();

  EXPECT_TRUE(registry.AddEnabled(extension));
  EXPECT_FALSE(
      registry.GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
  {
    base::Version version = registry.GetStoredVersion(extension_id);
    ASSERT_TRUE(version.IsValid());
    EXPECT_EQ(kVersionString,
              registry.GetStoredVersion(extension_id).GetString());
  }

  // Simulate terminating |extension|.
  EXPECT_TRUE(registry.RemoveEnabled(extension_id));
  EXPECT_TRUE(registry.AddTerminated(extension));
  EXPECT_TRUE(
      registry.GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
  {
    base::Version version = registry.GetStoredVersion(extension_id);
    ASSERT_TRUE(version.IsValid());
    EXPECT_EQ(kVersionString,
              registry.GetStoredVersion(extension_id).GetString());
  }
}

}  // namespace
}  // namespace extensions
