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

#include <functional>
#include <map>
#include <memory>
#include <string_view>

#include "base/containers/map_util.h"
#include "base/debug/alias.h"
#include "base/functional/callback.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/span_printf.h"
#include "base/strings/strcat.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature.h"

namespace extensions {

namespace {

// Writes |message| to the stack so that it shows up in the minidump, then
// crashes the current process.
//
// The prefix "e::" is used so that the crash can be quickly located.
//
// This is provided in feature_util because for some reason features are prone
// to mysterious crashes in named map lookups. For example see
// crbug.com/40361738 and crbug.com/40407279.
#define CRASH_WITH_MINIDUMP(message)                                  \
  {                                                                   \
    std::string message_copy(message);                                \
    char minidump[BUFSIZ];                                            \
    base::debug::Alias(&minidump);                                    \
    base::SpanPrintf(minidump, "e::%s:%d:\"%s\"", __FILE__, __LINE__, \
                     message_copy.c_str());                           \
    LOG(FATAL) << message_copy;                                       \
  }

class FeatureProviderStatic {
 public:
  FeatureProviderStatic() {
    TRACE_EVENT0("startup",
                 "extensions::FeatureProvider::FeatureProviderStatic");

    ExtensionsClient* client = ExtensionsClient::Get();
    feature_providers_["api"] = client->CreateFeatureProvider("api");
    feature_providers_["manifest"] = client->CreateFeatureProvider("manifest");
    feature_providers_["permission"] =
        client->CreateFeatureProvider("permission");
    feature_providers_["behavior"] = client->CreateFeatureProvider("behavior");
  }

  FeatureProviderStatic(const FeatureProviderStatic&) = delete;
  FeatureProviderStatic& operator=(const FeatureProviderStatic&) = delete;

  const FeatureProvider* GetFeatures(std::string_view name) const {
    auto* provider = base::FindPtrOrNull(feature_providers_, name);
    if (!provider) {
      CRASH_WITH_MINIDUMP(
          base::StrCat({"FeatureProvider \"", name, "\" not found"}));
    }
    return provider;
  }

 private:
  std::map<std::string, std::unique_ptr<FeatureProvider>, std::less<>>
      feature_providers_;
};

const FeatureProviderStatic& GetFeatureProviderStatic() {
  static base::NoDestructor<FeatureProviderStatic> instance;
  return *instance;
}

const Feature* GetFeatureFromProviderByName(std::string_view provider_name,
                                            std::string_view feature_name) {
  const Feature* feature =
      FeatureProvider::GetByName(provider_name)->GetFeature(feature_name);
  // We should always refer to existing features, but we can't CHECK here
  // due to flaky JSONReader fails, see: crbug.com/40302033, crbug.com/41248827
  DCHECK(feature) << "Feature \"" << feature_name << "\" not found in "
                  << "FeatureProvider \"" << provider_name << "\"";
  return feature;
}

}  // namespace

FeatureProvider::FeatureProvider() = default;
FeatureProvider::~FeatureProvider() = default;

// static
const FeatureProvider* FeatureProvider::GetByName(std::string_view name) {
  return GetFeatureProviderStatic().GetFeatures(name);
}

// static
const FeatureProvider* FeatureProvider::GetAPIFeatures() {
  return GetByName("api");
}

// static
const FeatureProvider* FeatureProvider::GetManifestFeatures() {
  return GetByName("manifest");
}

// static
const FeatureProvider* FeatureProvider::GetPermissionFeatures() {
  return GetByName("permission");
}

// static
const FeatureProvider* FeatureProvider::GetBehaviorFeatures() {
  return GetByName("behavior");
}

// static
const Feature* FeatureProvider::GetAPIFeature(std::string_view name) {
  return GetFeatureFromProviderByName("api", name);
}

// static
const Feature* FeatureProvider::GetManifestFeature(std::string_view name) {
  return GetFeatureFromProviderByName("manifest", name);
}

// static
const Feature* FeatureProvider::GetPermissionFeature(std::string_view name) {
  return GetFeatureFromProviderByName("permission", name);
}

// static
const Feature* FeatureProvider::GetBehaviorFeature(std::string_view name) {
  return GetFeatureFromProviderByName("behavior", name);
}

const Feature* FeatureProvider::GetFeature(std::string_view name) const {
  return base::FindPtrOrNull(features_, name);
}

const Feature* FeatureProvider::GetParent(const Feature& feature) const {
  if (feature.no_parent())
    return nullptr;

  std::vector<std::string_view> split = base::SplitStringPiece(
      feature.name(), ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (split.size() < 2)
    return nullptr;
  split.pop_back();
  return GetFeature(base::JoinString(split, "."));
}

// Children of a given API are named starting with parent.name()+".", which
// means they'll be contiguous in the sorted features_ registry.
std::vector<const Feature*> FeatureProvider::GetChildren(
    const Feature& parent) const {
  std::string prefix = base::StrCat({parent.name(), "."});
  const FeatureMap::const_iterator first_child = features_.lower_bound(prefix);

  // All children have names before (parent.name() + ('.'+1)).
  ++prefix.back();
  const FeatureMap::const_iterator after_children =
      features_.lower_bound(prefix);

  std::vector<const Feature*> result;
  result.reserve(std::distance(first_child, after_children));
  for (FeatureMap::const_iterator it = first_child; it != after_children;
       ++it) {
    if (!it->second->no_parent())
      result.push_back(it->second.get());
  }
  return result;
}

const FeatureMap& FeatureProvider::GetAllFeatures() const {
  return features_;
}

void FeatureProvider::AddStaticFeatures(
    base::span<const Feature* const> features) {
  features_.reserve(features_.size() + features.size());

  for (const Feature* feature : features) {
    CHECK(feature);
    const std::string_view feature_name = feature->name();
    const size_t previous_size = features_.size();
    // Generated entries arrive sorted, making end() the optimal insertion
    // hint; batches from other providers transparently fall back to lookup.
    features_.emplace_hint(features_.end(), feature_name, feature);
    CHECK_EQ(features_.size(), previous_size + 1u)
        << "Duplicate feature registration: " << feature_name;
  }
}

}  // namespace extensions
