// 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/common/extension_api.h"

#include <stddef.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "extensions/common/extension.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/features/simple_feature.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "url/gurl.h"

namespace extensions {

namespace {

const char* const kChildKinds[] = {"functions", "events"};

std::unique_ptr<base::DictionaryValue> LoadSchemaDictionary(
    const std::string& name,
    const base::StringPiece& schema) {
  std::string error_message;
  std::unique_ptr<base::Value> result(
      base::JSONReader::ReadAndReturnError(schema,
                                           base::JSON_PARSE_RFC,  // options
                                           NULL,                  // error code
                                           &error_message));

  // Tracking down http://crbug.com/121424
  char buf[128];
  base::snprintf(buf, arraysize(buf), "%s: (%d) '%s'", name.c_str(),
                 result.get() ? static_cast<int>(result->GetType()) : -1,
                 error_message.c_str());

  CHECK(result.get()) << error_message << " for schema " << schema;
  CHECK(result->IsType(base::Value::Type::DICTIONARY)) << " for schema "
                                                       << schema;
  return base::DictionaryValue::From(std::move(result));
}

const base::DictionaryValue* FindListItem(const base::ListValue* list,
                                          const std::string& property_name,
                                          const std::string& property_value) {
  for (size_t i = 0; i < list->GetSize(); ++i) {
    const base::DictionaryValue* item = NULL;
    CHECK(list->GetDictionary(i, &item))
        << property_value << "/" << property_name;
    std::string value;
    if (item->GetString(property_name, &value) && value == property_value)
      return item;
  }

  return NULL;
}

const base::DictionaryValue* GetSchemaChild(
    const base::DictionaryValue* schema_node,
    const std::string& child_name) {
  const base::DictionaryValue* child_node = NULL;
  for (size_t i = 0; i < arraysize(kChildKinds); ++i) {
    const base::ListValue* list_node = NULL;
    if (!schema_node->GetList(kChildKinds[i], &list_node))
      continue;
    child_node = FindListItem(list_node, "name", child_name);
    if (child_node)
      return child_node;
  }

  return NULL;
}

struct Static {
  Static()
      : api(ExtensionAPI::CreateWithDefaultConfiguration()) {
  }
  std::unique_ptr<ExtensionAPI> api;
};

base::LazyInstance<Static>::Leaky g_lazy_instance = LAZY_INSTANCE_INITIALIZER;

// May override |g_lazy_instance| for a test.
ExtensionAPI* g_shared_instance_for_test = NULL;

}  // namespace

// static
ExtensionAPI* ExtensionAPI::GetSharedInstance() {
  return g_shared_instance_for_test ? g_shared_instance_for_test
                                    : g_lazy_instance.Get().api.get();
}

// static
ExtensionAPI* ExtensionAPI::CreateWithDefaultConfiguration() {
  ExtensionAPI* api = new ExtensionAPI();
  api->InitDefaultConfiguration();
  return api;
}

// static
void ExtensionAPI::SplitDependencyName(const std::string& full_name,
                                       std::string* feature_type,
                                       std::string* feature_name) {
  size_t colon_index = full_name.find(':');
  if (colon_index == std::string::npos) {
    // TODO(aa): Remove this code when all API descriptions have been updated.
    *feature_type = "api";
    *feature_name = full_name;
    return;
  }

  *feature_type = full_name.substr(0, colon_index);
  *feature_name = full_name.substr(colon_index + 1);
}

ExtensionAPI::OverrideSharedInstanceForTest::OverrideSharedInstanceForTest(
    ExtensionAPI* testing_api)
    : original_api_(g_shared_instance_for_test) {
  g_shared_instance_for_test = testing_api;
}

ExtensionAPI::OverrideSharedInstanceForTest::~OverrideSharedInstanceForTest() {
  g_shared_instance_for_test = original_api_;
}

void ExtensionAPI::LoadSchema(const std::string& name,
                              const base::StringPiece& schema) {
  std::unique_ptr<base::DictionaryValue> schema_dict(
      LoadSchemaDictionary(name, schema));
  std::string schema_namespace;
  CHECK(schema_dict->GetString("namespace", &schema_namespace));
  schemas_[schema_namespace] = std::move(schema_dict);
}

ExtensionAPI::ExtensionAPI() : default_configuration_initialized_(false) {
}

ExtensionAPI::~ExtensionAPI() {
}

void ExtensionAPI::InitDefaultConfiguration() {
  const char* names[] = {"api", "manifest", "permission"};
  for (size_t i = 0; i < arraysize(names); ++i)
    RegisterDependencyProvider(names[i], FeatureProvider::GetByName(names[i]));

  default_configuration_initialized_ = true;
}

void ExtensionAPI::RegisterDependencyProvider(const std::string& name,
                                              const FeatureProvider* provider) {
  dependency_providers_[name] = provider;
}

bool ExtensionAPI::IsAnyFeatureAvailableToContext(
    const Feature& api,
    const Extension* extension,
    Feature::Context context,
    const GURL& url,
    CheckAliasStatus check_alias) {
  FeatureProviderMap::iterator provider = dependency_providers_.find("api");
  CHECK(provider != dependency_providers_.end());

  if (api.IsAvailableToContext(extension, context, url).is_available())
    return true;

  // Check to see if there are any parts of this API that are allowed in this
  // context.
  const std::vector<Feature*> features = provider->second->GetChildren(api);
  for (std::vector<Feature*>::const_iterator it = features.begin();
       it != features.end();
       ++it) {
    if ((*it)->IsAvailableToContext(extension, context, url).is_available())
      return true;
  }

  if (check_alias != CheckAliasStatus::ALLOWED)
    return false;

  const std::string& alias_name = api.alias();
  if (alias_name.empty())
    return false;

  const Feature* alias = provider->second->GetFeature(alias_name);
  CHECK(alias) << "Cannot find alias feature " << alias_name
               << " for API feature " << api.name();
  return IsAnyFeatureAvailableToContext(*alias, extension, context, url,
                                        CheckAliasStatus::NOT_ALLOWED);
}

Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name,
                                                const Extension* extension,
                                                Feature::Context context,
                                                const GURL& url,
                                                CheckAliasStatus check_alias) {
  Feature* feature = GetFeatureDependency(full_name);
  if (!feature) {
    return Feature::Availability(Feature::NOT_PRESENT,
                                 std::string("Unknown feature: ") + full_name);
  }

  Feature::Availability availability =
      feature->IsAvailableToContext(extension, context, url);
  if (availability.is_available() || check_alias != CheckAliasStatus::ALLOWED)
    return availability;

  Feature::Availability alias_availability =
      IsAliasAvailable(full_name, feature, extension, context, url);
  return alias_availability.is_available() ? alias_availability : availability;
}

base::StringPiece ExtensionAPI::GetSchemaStringPiece(
    const std::string& api_name) {
  DCHECK_EQ(api_name, GetAPINameFromFullName(api_name, nullptr));
  StringPieceMap::iterator cached = schema_strings_.find(api_name);
  if (cached != schema_strings_.end())
    return cached->second;

  ExtensionsClient* client = ExtensionsClient::Get();
  DCHECK(client);
  if (default_configuration_initialized_ &&
      client->IsAPISchemaGenerated(api_name)) {
    base::StringPiece schema = client->GetAPISchema(api_name);
    CHECK(!schema.empty());
    schema_strings_[api_name] = schema;
    return schema;
  }

  return base::StringPiece();
}

const base::DictionaryValue* ExtensionAPI::GetSchema(
    const std::string& full_name) {
  std::string child_name;
  std::string api_name = GetAPINameFromFullName(full_name, &child_name);

  const base::DictionaryValue* result = NULL;
  SchemaMap::iterator maybe_schema = schemas_.find(api_name);
  if (maybe_schema != schemas_.end()) {
    result = maybe_schema->second.get();
  } else {
    base::StringPiece schema_string = GetSchemaStringPiece(api_name);
    if (schema_string.empty())
      return nullptr;
    LoadSchema(api_name, schema_string);

    maybe_schema = schemas_.find(api_name);
    CHECK(schemas_.end() != maybe_schema);
    result = maybe_schema->second.get();
  }

  if (!child_name.empty())
    result = GetSchemaChild(result, child_name);

  return result;
}

Feature* ExtensionAPI::GetFeatureDependency(const std::string& full_name) {
  std::string feature_type;
  std::string feature_name;
  SplitDependencyName(full_name, &feature_type, &feature_name);

  FeatureProviderMap::iterator provider =
      dependency_providers_.find(feature_type);
  if (provider == dependency_providers_.end())
    return NULL;

  Feature* feature = provider->second->GetFeature(feature_name);
  // Try getting the feature for the parent API, if this was a child.
  if (!feature) {
    std::string child_name;
    feature = provider->second->GetFeature(
        GetAPINameFromFullName(feature_name, &child_name));
  }
  return feature;
}

std::string ExtensionAPI::GetAPINameFromFullName(const std::string& full_name,
                                                 std::string* child_name) {
  std::string api_name_candidate = full_name;
  ExtensionsClient* extensions_client = ExtensionsClient::Get();
  DCHECK(extensions_client);
  while (true) {
    if (IsKnownAPI(api_name_candidate, extensions_client)) {
      if (child_name) {
        if (api_name_candidate.length() < full_name.length())
          *child_name = full_name.substr(api_name_candidate.length() + 1);
        else
          *child_name = "";
      }
      return api_name_candidate;
    }

    size_t last_dot_index = api_name_candidate.rfind('.');
    if (last_dot_index == std::string::npos)
      break;

    api_name_candidate = api_name_candidate.substr(0, last_dot_index);
  }

  if (child_name)
    *child_name = "";
  return std::string();
}

bool ExtensionAPI::IsKnownAPI(const std::string& name,
                              ExtensionsClient* client) {
  return schemas_.find(name) != schemas_.end() ||
         client->IsAPISchemaGenerated(name);
}

Feature::Availability ExtensionAPI::IsAliasAvailable(
    const std::string& full_name,
    Feature* feature,
    const Extension* extension,
    Feature::Context context,
    const GURL& url) {
  const std::string& alias = feature->alias();
  if (alias.empty())
    return Feature::Availability(Feature::NOT_PRESENT, "Alias not defined");

  FeatureProviderMap::iterator provider = dependency_providers_.find("api");
  CHECK(provider != dependency_providers_.end());

  // Check if there is a child feature associated with full name for alias API.
  // This is to ensure that the availability of the feature associated with the
  // aliased |full_name| is properly determined in case the feature in question
  // is a child feature. For example, if API foo has an alias fooAlias, which
  // has a child feature fooAlias.method, aliased foo.method availability should
  // be determined using fooAlias.method feature, rather than fooAlias feature.
  std::string child_name;
  GetAPINameFromFullName(full_name, &child_name);
  std::string full_alias_name = alias + "." + child_name;
  Feature* alias_feature = provider->second->GetFeature(full_alias_name);

  // If there is no child feature, use the alias API feature to check
  // availability.
  if (!alias_feature)
    alias_feature = provider->second->GetFeature(alias);

  CHECK(alias_feature) << "Cannot find alias feature " << alias
                       << " for API feature " << feature->name();

  return alias_feature->IsAvailableToContext(extension, context, url);
}

}  // namespace extensions
