// Copyright (c) 2012 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 "chrome/common/extensions/api/extension_api.h"

#include <string>
#include <vector>

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_builder.h"
#include "chrome/common/extensions/extension_test_util.h"
#include "chrome/common/extensions/features/api_feature.h"
#include "chrome/common/extensions/features/base_feature_provider.h"
#include "chrome/common/extensions/features/simple_feature.h"
#include "chrome/common/extensions/value_builder.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

using extension_test_util::BuildExtension;

SimpleFeature* CreateAPIFeature() {
  return new APIFeature();
}

TEST(ExtensionAPITest, Creation) {
  ExtensionAPI* shared_instance = ExtensionAPI::GetSharedInstance();
  EXPECT_EQ(shared_instance, ExtensionAPI::GetSharedInstance());

  scoped_ptr<ExtensionAPI> new_instance(
      ExtensionAPI::CreateWithDefaultConfiguration());
  EXPECT_NE(new_instance.get(),
            scoped_ptr<ExtensionAPI>(
                ExtensionAPI::CreateWithDefaultConfiguration()).get());

  ExtensionAPI empty_instance;

  struct {
    ExtensionAPI* api;
    bool expect_populated;
  } test_data[] = {
    { shared_instance, true },
    { new_instance.get(), true },
    { &empty_instance, false }
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    EXPECT_EQ(test_data[i].expect_populated,
              test_data[i].api->GetSchema("bookmarks.create") != NULL);
  }
}

TEST(ExtensionAPITest, SplitDependencyName) {
  struct {
    std::string input;
    std::string expected_feature_type;
    std::string expected_feature_name;
  } test_data[] = {
    { "", "api", "" },  // assumes "api" when no type is present
    { "foo", "api", "foo" },
    { "foo:", "foo", "" },
    { ":foo", "", "foo" },
    { "foo:bar", "foo", "bar" },
    { "foo:bar.baz", "foo", "bar.baz" }
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    std::string feature_type;
    std::string feature_name;
    ExtensionAPI::SplitDependencyName(test_data[i].input, &feature_type,
                                      &feature_name);
    EXPECT_EQ(test_data[i].expected_feature_type, feature_type) << i;
    EXPECT_EQ(test_data[i].expected_feature_name, feature_name) << i;
  }
}

TEST(ExtensionAPITest, IsPrivileged) {
  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());

  EXPECT_FALSE(extension_api->IsPrivileged("runtime.connect"));
  EXPECT_FALSE(extension_api->IsPrivileged("runtime.onConnect"));
  EXPECT_FALSE(extension_api->IsPrivileged("runtime.lastError"));

  // Exists, but privileged.
  EXPECT_TRUE(extension_api->IsPrivileged("extension.getViews"));
  EXPECT_TRUE(extension_api->IsPrivileged("history.search"));

  // Whole APIs that are unprivileged.
  EXPECT_FALSE(extension_api->IsPrivileged("app.getDetails"));
  EXPECT_FALSE(extension_api->IsPrivileged("app.isInstalled"));
  EXPECT_FALSE(extension_api->IsPrivileged("storage.local"));
  EXPECT_FALSE(extension_api->IsPrivileged("storage.local.onChanged"));
  EXPECT_FALSE(extension_api->IsPrivileged("storage.local.set"));
  EXPECT_FALSE(extension_api->IsPrivileged("storage.local.MAX_ITEMS"));
  EXPECT_FALSE(extension_api->IsPrivileged("storage.set"));
}

TEST(ExtensionAPITest, IsPrivilegedFeatures) {
  struct {
    std::string api_full_name;
    bool expect_is_privilged;
  } test_data[] = {
    { "test1", false },
    { "test1.foo", true },
    { "test2", true },
    { "test2.foo", false },
    { "test2.bar", false },
    { "test2.baz", true },
    { "test3", false },
    { "test3.foo", true },
    { "test4", false }
  };

  base::FilePath api_features_path;
  PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
  api_features_path = api_features_path.AppendASCII("extensions")
      .AppendASCII("extension_api_unittest")
      .AppendASCII("privileged_api_features.json");

  std::string api_features_str;
  ASSERT_TRUE(file_util::ReadFileToString(
      api_features_path, &api_features_str)) << "privileged_api_features.json";

  scoped_ptr<base::DictionaryValue> value(static_cast<base::DictionaryValue*>(
      base::JSONReader::Read(api_features_str)));
  BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    ExtensionAPI api;
    api.RegisterDependencyProvider("api", &api_feature_provider);
    EXPECT_EQ(test_data[i].expect_is_privilged,
              api.IsPrivileged(test_data[i].api_full_name)) << i;
  }
}

TEST(ExtensionAPITest, APIFeatures) {
  struct {
    std::string api_full_name;
    bool expect_is_available;
    Feature::Context context;
    GURL url;
  } test_data[] = {
    { "test1", false, Feature::WEB_PAGE_CONTEXT, GURL() },
    { "test1", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
    { "test1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "test2", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
    { "test2", false, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://google.com") },
    { "test2.foo", false, Feature::WEB_PAGE_CONTEXT,
        GURL("http://google.com") },
    { "test2.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "test3", false, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
    { "test3.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://google.com") },
    { "test3.foo", true, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://bad.com") },
    { "test4", true, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://bad.com") },
    { "test4.foo", false, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://bad.com") },
    { "test4.foo", false, Feature::UNBLESSED_EXTENSION_CONTEXT,
        GURL("http://bad.com") },
    { "test4.foo.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "test5", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
    { "test5", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
    { "test5.blah", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
    { "test5.blah", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
    { "test6", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "test6.foo", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "test7", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
    { "test7.foo", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
    { "test7.foo", true, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
    { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://bar.com") },
    { "test7.bar", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },

    // Test parent/child.
    { "parent1", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent1", false, Feature::WEB_PAGE_CONTEXT, GURL("http://foo.com") },
    { "parent1.child1", false, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent1.child1", true, Feature::WEB_PAGE_CONTEXT,
        GURL("http://foo.com") },
    { "parent1.child2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent1.child2", false, Feature::WEB_PAGE_CONTEXT,
        GURL("http://foo.com") },
    { "parent2", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent2", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent2", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent2.child3", false, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent2.child3", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent2.child3", false, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent2.child3.child.child", true, Feature::CONTENT_SCRIPT_CONTEXT,
        GURL() },
    { "parent2.child3.child.child", false, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL() },
    { "parent2.child3.child.child", true, Feature::UNBLESSED_EXTENSION_CONTEXT,
        GURL() },
    { "parent3", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent3", false, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent3", false, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent3.noparent", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent3.noparent", true, Feature::BLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent3.noparent", true, Feature::UNBLESSED_EXTENSION_CONTEXT, GURL() },
    { "parent3.noparent.child", true, Feature::CONTENT_SCRIPT_CONTEXT, GURL() },
    { "parent3.noparent.child", true, Feature::BLESSED_EXTENSION_CONTEXT,
        GURL() },
    { "parent3.noparent.child", true, Feature::UNBLESSED_EXTENSION_CONTEXT,
        GURL() }
  };

  base::FilePath api_features_path;
  PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
  api_features_path = api_features_path.AppendASCII("extensions")
      .AppendASCII("extension_api_unittest")
      .AppendASCII("api_features.json");

  std::string api_features_str;
  ASSERT_TRUE(file_util::ReadFileToString(
      api_features_path, &api_features_str)) << "api_features.json";

  scoped_ptr<base::DictionaryValue> value(static_cast<base::DictionaryValue*>(
      base::JSONReader::Read(api_features_str)));
  BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    ExtensionAPI api;
    api.RegisterDependencyProvider("api", &api_feature_provider);
    for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
         iter.Advance()) {
      if (iter.key().find(".") == std::string::npos)
        api.RegisterSchemaResource(iter.key(), 0);
    }

    EXPECT_EQ(test_data[i].expect_is_available,
              api.IsAvailable(test_data[i].api_full_name,
                              NULL,
                              test_data[i].context,
                              test_data[i].url).is_available()) << i;
  }
}

TEST(ExtensionAPITest, IsAnyFeatureAvailableToContext) {
  scoped_refptr<const Extension> app = ExtensionBuilder()
    .SetManifest(DictionaryBuilder()
      .Set("name", "app")
      .Set("app", DictionaryBuilder()
        .Set("background", DictionaryBuilder()
          .Set("scripts", ListBuilder().Append("background.js"))))
      .Set("version", "1")
      .Set("manifest_version", 2)).Build();
  scoped_refptr<const Extension> extension = ExtensionBuilder()
    .SetManifest(DictionaryBuilder()
      .Set("name", "extension")
      .Set("version", "1")
      .Set("manifest_version", 2)).Build();

  struct {
    std::string api_full_name;
    bool expect_is_available;
    Feature::Context context;
    const Extension* extension;
    GURL url;
  } test_data[] = {
    { "test1", false, Feature::WEB_PAGE_CONTEXT, NULL, GURL() },
    { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, NULL, GURL() },
    { "test1", false, Feature::UNBLESSED_EXTENSION_CONTEXT, app.get(), GURL() },
    { "test1", true, Feature::UNBLESSED_EXTENSION_CONTEXT, extension.get(),
        GURL() },
    { "test2", true, Feature::CONTENT_SCRIPT_CONTEXT, NULL, GURL() },
    { "test2", true, Feature::WEB_PAGE_CONTEXT, NULL,
        GURL("http://google.com") },
    { "test2.foo", false, Feature::WEB_PAGE_CONTEXT, NULL,
        GURL("http://google.com") },
    { "test3", true, Feature::CONTENT_SCRIPT_CONTEXT, NULL, GURL() },
    { "test3", true, Feature::WEB_PAGE_CONTEXT, NULL, GURL("http://foo.com") },
    { "test4.foo", true, Feature::CONTENT_SCRIPT_CONTEXT, NULL, GURL() },
    { "test7", false, Feature::WEB_PAGE_CONTEXT, NULL,
        GURL("http://google.com") },
    { "test7", true, Feature::WEB_PAGE_CONTEXT, NULL, GURL("http://foo.com") },
    { "test7", false, Feature::WEB_PAGE_CONTEXT, NULL, GURL("http://bar.com") }
  };

  base::FilePath api_features_path;
  PathService::Get(chrome::DIR_TEST_DATA, &api_features_path);
  api_features_path = api_features_path.AppendASCII("extensions")
      .AppendASCII("extension_api_unittest")
      .AppendASCII("api_features.json");

  std::string api_features_str;
  ASSERT_TRUE(file_util::ReadFileToString(
      api_features_path, &api_features_str)) << "api_features.json";

  scoped_ptr<base::DictionaryValue> value(static_cast<base::DictionaryValue*>(
      base::JSONReader::Read(api_features_str)));
  BaseFeatureProvider api_feature_provider(*value, CreateAPIFeature);

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    ExtensionAPI api;
    api.RegisterDependencyProvider("api", &api_feature_provider);
    for (base::DictionaryValue::Iterator iter(*value); !iter.IsAtEnd();
         iter.Advance()) {
      if (iter.key().find(".") == std::string::npos)
        api.RegisterSchemaResource(iter.key(), 0);
    }

    EXPECT_EQ(test_data[i].expect_is_available,
              api.IsAnyFeatureAvailableToContext(test_data[i].api_full_name,
                                                 test_data[i].extension,
                                                 test_data[i].context,
                                                 test_data[i].url)) << i;
  }
}

TEST(ExtensionAPITest, LazyGetSchema) {
  scoped_ptr<ExtensionAPI> apis(ExtensionAPI::CreateWithDefaultConfiguration());

  EXPECT_EQ(NULL, apis->GetSchema(std::string()));
  EXPECT_EQ(NULL, apis->GetSchema(std::string()));
  EXPECT_EQ(NULL, apis->GetSchema("experimental"));
  EXPECT_EQ(NULL, apis->GetSchema("experimental"));
  EXPECT_EQ(NULL, apis->GetSchema("foo"));
  EXPECT_EQ(NULL, apis->GetSchema("foo"));

  EXPECT_TRUE(apis->GetSchema("experimental.dns"));
  EXPECT_TRUE(apis->GetSchema("experimental.dns"));
  EXPECT_TRUE(apis->GetSchema("extension"));
  EXPECT_TRUE(apis->GetSchema("extension"));
  EXPECT_TRUE(apis->GetSchema("infobars"));
  EXPECT_TRUE(apis->GetSchema("infobars"));
  EXPECT_TRUE(apis->GetSchema("omnibox"));
  EXPECT_TRUE(apis->GetSchema("omnibox"));
  EXPECT_TRUE(apis->GetSchema("storage"));
  EXPECT_TRUE(apis->GetSchema("storage"));
}

scoped_refptr<Extension> CreateExtensionWithPermissions(
    const std::set<std::string>& permissions) {
  base::DictionaryValue manifest;
  manifest.SetString("name", "extension");
  manifest.SetString("version", "1.0");
  manifest.SetInteger("manifest_version", 2);
  {
    scoped_ptr<base::ListValue> permissions_list(new base::ListValue());
    for (std::set<std::string>::const_iterator i = permissions.begin();
        i != permissions.end(); ++i) {
      permissions_list->Append(new base::StringValue(*i));
    }
    manifest.Set("permissions", permissions_list.release());
  }

  std::string error;
  scoped_refptr<Extension> extension(Extension::Create(
      base::FilePath(), Manifest::UNPACKED,
      manifest, Extension::NO_FLAGS, &error));
  CHECK(extension.get());
  CHECK(error.empty());

  return extension;
}

scoped_refptr<Extension> CreateExtensionWithPermission(
    const std::string& permission) {
  std::set<std::string> permissions;
  permissions.insert(permission);
  return CreateExtensionWithPermissions(permissions);
}

TEST(ExtensionAPITest, ExtensionWithUnprivilegedAPIs) {
  scoped_refptr<Extension> extension;
  {
    std::set<std::string> permissions;
    permissions.insert("storage");
    permissions.insert("history");
    extension = CreateExtensionWithPermissions(permissions);
  }

  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());

  // "runtime" has privileged parts that should not be accessed by content
  // scripts.
  EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
      "runtime.getBackgroundPage",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));
  EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
      "runtime.sendNativeMessage",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));
  // "runtime" also has unprivileged parts.
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "runtime.sendMessage",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "runtime.id",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));

  // "storage" is completely unprivileged.
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "storage",
      NULL,
      Feature::BLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "storage",
      NULL,
      Feature::UNBLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "storage",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));

  // "extension" is partially unprivileged.
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "extension",
      NULL,
      Feature::BLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "extension",
      NULL,
      Feature::UNBLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "extension",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));

  // "history" is entirely privileged.
  EXPECT_TRUE(extension_api->IsAnyFeatureAvailableToContext(
      "history",
      NULL,
      Feature::BLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
      "history",
      NULL,
      Feature::UNBLESSED_EXTENSION_CONTEXT,
      GURL()));
  EXPECT_FALSE(extension_api->IsAnyFeatureAvailableToContext(
      "history",
      NULL,
      Feature::CONTENT_SCRIPT_CONTEXT,
      GURL()));
}

scoped_refptr<Extension> CreateHostedApp() {
  base::DictionaryValue values;
  values.SetString(manifest_keys::kName, "test");
  values.SetString(manifest_keys::kVersion, "0.1");
  values.Set(manifest_keys::kWebURLs, new base::ListValue());
  values.SetString(manifest_keys::kLaunchWebURL,
                   "http://www.example.com");
  std::string error;
  scoped_refptr<Extension> extension(Extension::Create(
      base::FilePath(), Manifest::INTERNAL, values, Extension::NO_FLAGS,
      &error));
  CHECK(extension.get());
  return extension;
}

scoped_refptr<Extension> CreatePackagedAppWithPermissions(
    const std::set<std::string>& permissions) {
  base::DictionaryValue values;
  values.SetString(manifest_keys::kName, "test");
  values.SetString(manifest_keys::kVersion, "0.1");
  values.SetString(manifest_keys::kPlatformAppBackground,
      "http://www.example.com");

  base::DictionaryValue* app = new base::DictionaryValue();
  base::DictionaryValue* background = new base::DictionaryValue();
  base::ListValue* scripts = new base::ListValue();
  scripts->Append(new base::StringValue("test.js"));
  background->Set("scripts", scripts);
  app->Set("background", background);
  values.Set(manifest_keys::kApp, app);
  {
    scoped_ptr<base::ListValue> permissions_list(new base::ListValue());
    for (std::set<std::string>::const_iterator i = permissions.begin();
        i != permissions.end(); ++i) {
      permissions_list->Append(new base::StringValue(*i));
    }
    values.Set("permissions", permissions_list.release());
  }

  std::string error;
  scoped_refptr<Extension> extension(Extension::Create(
      base::FilePath(), Manifest::INTERNAL, values, Extension::NO_FLAGS,
      &error));
  CHECK(extension.get()) << error;
  return extension;
}

TEST(ExtensionAPITest, HostedAppPermissions) {
  scoped_refptr<Extension> extension = CreateHostedApp();

  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());

  // "runtime" and "tabs" should not be available in hosted apps.
  EXPECT_FALSE(extension_api->IsAvailable("runtime",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
  EXPECT_FALSE(extension_api->IsAvailable("runtime.id",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
  EXPECT_FALSE(extension_api->IsAvailable("runtime.sendMessage",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
  EXPECT_FALSE(extension_api->IsAvailable("runtime.sendNativeMessage",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
  EXPECT_FALSE(extension_api->IsAvailable("tabs.create",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
}

TEST(ExtensionAPITest, AppAndFriendsAvailability) {

  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());

  // Make sure chrome.app.runtime and chrome.app.window are available to apps,
  // and chrome.app is not.
  {
    std::set<std::string> permissions;
    permissions.insert("app.runtime");
    permissions.insert("app.window");
    scoped_refptr<Extension> extension =
        CreatePackagedAppWithPermissions(permissions);
    EXPECT_FALSE(extension_api->IsAvailable(
        "app",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
    EXPECT_TRUE(extension_api->IsAvailable(
        "app.runtime",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
    EXPECT_TRUE(extension_api->IsAvailable(
        "app.window",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
  }
  // Make sure chrome.app.runtime and chrome.app.window are not available to
  // extensions, and chrome.app is.
  {
    std::set<std::string> permissions;
    scoped_refptr<Extension> extension =
        CreateExtensionWithPermissions(permissions);
    EXPECT_TRUE(extension_api->IsAvailable(
        "app",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
    EXPECT_FALSE(extension_api->IsAvailable(
        "app.runtime",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
    EXPECT_FALSE(extension_api->IsAvailable(
        "app.window",
        extension.get(),
        Feature::BLESSED_EXTENSION_CONTEXT,
        GURL("http://foo.com")).is_available());
  }
}

TEST(ExtensionAPITest, ExtensionWithDependencies) {
  // Extension with the "ttsEngine" permission but not the "tts" permission; it
  // should not automatically get "tts" permission.
  {
    scoped_refptr<Extension> extension =
        CreateExtensionWithPermission("ttsEngine");
    scoped_ptr<ExtensionAPI> api(
        ExtensionAPI::CreateWithDefaultConfiguration());
    EXPECT_TRUE(api->IsAvailable("ttsEngine",
                                 extension.get(),
                                 Feature::BLESSED_EXTENSION_CONTEXT,
                                 GURL()).is_available());
    EXPECT_FALSE(api->IsAvailable("tts",
                                  extension.get(),
                                  Feature::BLESSED_EXTENSION_CONTEXT,
                                  GURL()).is_available());
  }

  // Conversely, extension with the "tts" permission but not the "ttsEngine"
  // permission shouldn't get the "ttsEngine" permission.
  {
    scoped_refptr<Extension> extension =
        CreateExtensionWithPermission("tts");
    scoped_ptr<ExtensionAPI> api(
        ExtensionAPI::CreateWithDefaultConfiguration());
    EXPECT_FALSE(api->IsAvailable("ttsEngine",
                                  extension.get(),
                                  Feature::BLESSED_EXTENSION_CONTEXT,
                                  GURL()).is_available());
    EXPECT_TRUE(api->IsAvailable("tts",
                                 extension.get(),
                                 Feature::BLESSED_EXTENSION_CONTEXT,
                                 GURL()).is_available());
  }
}

bool MatchesURL(
    ExtensionAPI* api, const std::string& api_name, const std::string& url) {
  return api->IsAvailable(
      api_name, NULL, Feature::WEB_PAGE_CONTEXT, GURL(url)).is_available();
}

TEST(ExtensionAPITest, URLMatching) {
  scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());

  // "app" API is available to all URLs that content scripts can be injected.
  EXPECT_TRUE(MatchesURL(api.get(), "app", "http://example.com/example.html"));
  EXPECT_TRUE(MatchesURL(api.get(), "app", "https://blah.net"));
  EXPECT_TRUE(MatchesURL(api.get(), "app", "file://somefile.html"));

  // But not internal URLs.
  EXPECT_FALSE(MatchesURL(api.get(), "app", "about:flags"));
  EXPECT_FALSE(MatchesURL(api.get(), "app", "chrome://flags"));

  // "app" should be available to chrome-extension URLs.
  EXPECT_TRUE(MatchesURL(api.get(), "app",
                          "chrome-extension://fakeextension"));

  // "storage" API (for example) isn't available to any URLs.
  EXPECT_FALSE(MatchesURL(api.get(), "storage",
                          "http://example.com/example.html"));
  EXPECT_FALSE(MatchesURL(api.get(), "storage", "https://blah.net"));
  EXPECT_FALSE(MatchesURL(api.get(), "storage", "file://somefile.html"));
  EXPECT_FALSE(MatchesURL(api.get(), "storage", "about:flags"));
  EXPECT_FALSE(MatchesURL(api.get(), "storage", "chrome://flags"));
  EXPECT_FALSE(MatchesURL(api.get(), "storage",
                          "chrome-extension://fakeextension"));
}

TEST(ExtensionAPITest, GetAPINameFromFullName) {
  struct {
    std::string input;
    std::string api_name;
    std::string child_name;
  } test_data[] = {
    { "", "", "" },
    { "unknown", "", "" },
    { "bookmarks", "bookmarks", "" },
    { "bookmarks.", "bookmarks", "" },
    { ".bookmarks", "", "" },
    { "bookmarks.create", "bookmarks", "create" },
    { "bookmarks.create.", "bookmarks", "create." },
    { "bookmarks.create.monkey", "bookmarks", "create.monkey" },
    { "bookmarkManagerPrivate", "bookmarkManagerPrivate", "" },
    { "bookmarkManagerPrivate.copy", "bookmarkManagerPrivate", "copy" }
  };

  scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    std::string child_name;
    std::string api_name = api->GetAPINameFromFullName(test_data[i].input,
                                                       &child_name);
    EXPECT_EQ(test_data[i].api_name, api_name) << test_data[i].input;
    EXPECT_EQ(test_data[i].child_name, child_name) << test_data[i].input;
  }
}

TEST(ExtensionAPITest, DefaultConfigurationFeatures) {
  scoped_ptr<ExtensionAPI> api(ExtensionAPI::CreateWithDefaultConfiguration());

  SimpleFeature* bookmarks = static_cast<SimpleFeature*>(
      api->GetFeatureDependency("api:bookmarks"));
  SimpleFeature* bookmarks_create = static_cast<SimpleFeature*>(
      api->GetFeatureDependency("api:bookmarks.create"));

  struct {
    SimpleFeature* feature;
    // TODO(aa): More stuff to test over time.
  } test_data[] = {
    { bookmarks },
    { bookmarks_create }
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    SimpleFeature* feature = test_data[i].feature;
    ASSERT_TRUE(feature) << i;

    EXPECT_TRUE(feature->whitelist()->empty());
    EXPECT_TRUE(feature->extension_types()->empty());

    EXPECT_EQ(1u, feature->GetContexts()->size());
    EXPECT_TRUE(feature->GetContexts()->count(
        Feature::BLESSED_EXTENSION_CONTEXT));

    EXPECT_EQ(Feature::UNSPECIFIED_LOCATION, feature->location());
    EXPECT_EQ(Feature::UNSPECIFIED_PLATFORM, feature->platform());
    EXPECT_EQ(0, feature->min_manifest_version());
    EXPECT_EQ(0, feature->max_manifest_version());
  }
}

TEST(ExtensionAPITest, FeaturesRequireContexts) {
  // TODO(cduvall): Make this check API featues.
  scoped_ptr<base::DictionaryValue> api_features1(new base::DictionaryValue());
  scoped_ptr<base::DictionaryValue> api_features2(new base::DictionaryValue());
  base::DictionaryValue* test1 = new base::DictionaryValue();
  base::DictionaryValue* test2 = new base::DictionaryValue();
  base::ListValue* contexts = new base::ListValue();
  contexts->Append(new base::StringValue("content_script"));
  test1->Set("contexts", contexts);
  test1->SetString("channel", "stable");
  test2->SetString("channel", "stable");
  api_features1->Set("test", test1);
  api_features2->Set("test", test2);

  struct {
    base::DictionaryValue* api_features;
    bool expect_success;
  } test_data[] = {
    { api_features1.get(), true },
    { api_features2.get(), false }
  };


  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
    BaseFeatureProvider api_feature_provider(*test_data[i].api_features,
                                             CreateAPIFeature);
    Feature* feature = api_feature_provider.GetFeature("test");
    EXPECT_EQ(test_data[i].expect_success, feature != NULL) << i;
  }
}

static void GetDictionaryFromList(const base::DictionaryValue* schema,
                                  const std::string& list_name,
                                  const int list_index,
                                  const base::DictionaryValue** out) {
  const base::ListValue* list;
  EXPECT_TRUE(schema->GetList(list_name, &list));
  EXPECT_TRUE(list->GetDictionary(list_index, out));
}

TEST(ExtensionAPITest, TypesHaveNamespace) {
  base::FilePath manifest_path;
  PathService::Get(chrome::DIR_TEST_DATA, &manifest_path);
  manifest_path = manifest_path.AppendASCII("extensions")
      .AppendASCII("extension_api_unittest")
      .AppendASCII("types_have_namespace.json");

  std::string manifest_str;
  ASSERT_TRUE(file_util::ReadFileToString(manifest_path, &manifest_str))
      << "Failed to load: " << manifest_path.value();

  ExtensionAPI api;
  api.RegisterSchemaResource("test.foo", 0);
  api.LoadSchema("test.foo", manifest_str);

  const base::DictionaryValue* schema = api.GetSchema("test.foo");

  const base::DictionaryValue* dict;
  const base::DictionaryValue* sub_dict;
  std::string type;

  GetDictionaryFromList(schema, "types", 0, &dict);
  EXPECT_TRUE(dict->GetString("id", &type));
  EXPECT_EQ("test.foo.TestType", type);
  EXPECT_TRUE(dict->GetString("customBindings", &type));
  EXPECT_EQ("test.foo.TestType", type);
  EXPECT_TRUE(dict->GetDictionary("properties", &sub_dict));
  const base::DictionaryValue* property;
  EXPECT_TRUE(sub_dict->GetDictionary("foo", &property));
  EXPECT_TRUE(property->GetString("$ref", &type));
  EXPECT_EQ("test.foo.OtherType", type);
  EXPECT_TRUE(sub_dict->GetDictionary("bar", &property));
  EXPECT_TRUE(property->GetString("$ref", &type));
  EXPECT_EQ("fully.qualified.Type", type);

  GetDictionaryFromList(schema, "functions", 0, &dict);
  GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("test.foo.TestType", type);
  EXPECT_TRUE(dict->GetDictionary("returns", &sub_dict));
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("fully.qualified.Type", type);

  GetDictionaryFromList(schema, "functions", 1, &dict);
  GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("fully.qualified.Type", type);
  EXPECT_TRUE(dict->GetDictionary("returns", &sub_dict));
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("test.foo.TestType", type);

  GetDictionaryFromList(schema, "events", 0, &dict);
  GetDictionaryFromList(dict, "parameters", 0, &sub_dict);
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("test.foo.TestType", type);
  GetDictionaryFromList(dict, "parameters", 1, &sub_dict);
  EXPECT_TRUE(sub_dict->GetString("$ref", &type));
  EXPECT_EQ("fully.qualified.Type", type);
}

// Tests API availability with an empty manifest.
TEST(ExtensionAPITest, NoPermissions) {
  const struct {
    const char* permission_name;
    bool expect_success;
  } kTests[] = {
    // Test default module/package permission.
    { "extension",      true },
    { "i18n",           true },
    { "permissions",    true },
    { "runtime",        true },
    { "test",           true },
    // These require manifest keys.
    { "browserAction",  false },
    { "pageAction",     false },
    { "pageActions",    false },
    // Some negative tests.
    { "bookmarks",      false },
    { "cookies",        false },
    { "history",        false },
    // Make sure we find the module name after stripping '.'
    { "runtime.abcd.onStartup",  true },
    // Test Tabs/Windows functions.
    { "tabs.create",      true },
    { "tabs.duplicate",   true },
    { "tabs.onRemoved",   true },
    { "tabs.remove",      true },
    { "tabs.update",      true },
    { "tabs.getSelected", true },
    { "tabs.onUpdated",   true },
    { "windows.get",      true },
    { "windows.create",   true },
    { "windows.remove",   true },
    { "windows.update",   true },
    // Test some whitelisted functions. These require no permissions.
    { "app.getDetails",           true },
    { "app.getDetailsForFrame",   true },
    { "app.getIsInstalled",       true },
    { "app.installState",         true },
    { "app.runningState",         true },
    { "management.getPermissionWarningsByManifest", true },
    { "management.uninstallSelf", true },
    // But other functions in those modules do.
    { "management.getPermissionWarningsById", false },
  };

  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());
  scoped_refptr<Extension> extension =
      BuildExtension(ExtensionBuilder().Pass()).Build();

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
    EXPECT_EQ(kTests[i].expect_success,
              extension_api->IsAvailable(kTests[i].permission_name,
                                         extension.get(),
                                         Feature::BLESSED_EXTENSION_CONTEXT,
                                         GURL()).is_available())
        << "Permission being tested: " << kTests[i].permission_name;
  }
}

// Tests that permissions that require manifest keys are available when those
// keys are present.
TEST(ExtensionAPITest, ManifestKeys) {
  scoped_ptr<ExtensionAPI> extension_api(
      ExtensionAPI::CreateWithDefaultConfiguration());

  scoped_refptr<Extension> extension =
      BuildExtension(ExtensionBuilder().Pass())
      .MergeManifest(DictionaryBuilder().Set("browser_action",
                                             DictionaryBuilder().Pass()))
      .Build();

  EXPECT_TRUE(extension_api->IsAvailable("browserAction",
                                         extension.get(),
                                         Feature::BLESSED_EXTENSION_CONTEXT,
                                         GURL()).is_available());
  EXPECT_FALSE(extension_api->IsAvailable("pageAction",
                                          extension.get(),
                                          Feature::BLESSED_EXTENSION_CONTEXT,
                                          GURL()).is_available());
}

}  // namespace extensions
