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

#include <utility>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/crx_file/id_util.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/install_warning.h"
#include "extensions/common/manifest_constants.h"

namespace extensions {

namespace keys = manifest_keys;

namespace {

// Rank extension locations in a way that allows
// Manifest::GetHigherPriorityLocation() to compare locations.
// An extension installed from two locations will have the location
// with the higher rank, as returned by this function. The actual
// integer values may change, and should never be persisted.
int GetLocationRank(Manifest::Location location) {
  const int kInvalidRank = -1;
  int rank = kInvalidRank;  // Will CHECK that rank is not kInvalidRank.

  switch (location) {
    // Component extensions can not be overriden by any other type.
    case Manifest::COMPONENT:
      rank = 9;
      break;

    case Manifest::EXTERNAL_COMPONENT:
      rank = 8;
      break;

    // Policy controlled extensions may not be overridden by any type
    // that is not part of chrome.
    case Manifest::EXTERNAL_POLICY:
      rank = 7;
      break;

    case Manifest::EXTERNAL_POLICY_DOWNLOAD:
      rank = 6;
      break;

    // A developer-loaded extension should override any installed type
    // that a user can disable. Anything specified on the command-line should
    // override one loaded via the extensions UI.
    case Manifest::COMMAND_LINE:
      rank = 5;
      break;

    case Manifest::UNPACKED:
      rank = 4;
      break;

    // The relative priority of various external sources is not important,
    // but having some order ensures deterministic behavior.
    case Manifest::EXTERNAL_REGISTRY:
      rank = 3;
      break;

    case Manifest::EXTERNAL_PREF:
      rank = 2;
      break;

    case Manifest::EXTERNAL_PREF_DOWNLOAD:
      rank = 1;
      break;

    // User installed extensions are overridden by any external type.
    case Manifest::INTERNAL:
      rank = 0;
      break;

    default:
      NOTREACHED() << "Need to add new extension location " << location;
  }

  CHECK(rank != kInvalidRank);
  return rank;
}

}  // namespace

// static
Manifest::Location Manifest::GetHigherPriorityLocation(
    Location loc1, Location loc2) {
  if (loc1 == loc2)
    return loc1;

  int loc1_rank = GetLocationRank(loc1);
  int loc2_rank = GetLocationRank(loc2);

  // If two different locations have the same rank, then we can not
  // deterministicly choose a location.
  CHECK(loc1_rank != loc2_rank);

  // Highest rank has highest priority.
  return (loc1_rank > loc2_rank ? loc1 : loc2 );
}

Manifest::Manifest(Location location,
                   std::unique_ptr<base::DictionaryValue> value)
    : location_(location), value_(std::move(value)), type_(TYPE_UNKNOWN) {
  if (value_->HasKey(keys::kTheme)) {
    type_ = TYPE_THEME;
  } else if (value_->HasKey(keys::kExport)) {
    type_ = TYPE_SHARED_MODULE;
  } else if (value_->HasKey(keys::kApp)) {
    if (value_->Get(keys::kWebURLs, NULL) ||
        value_->Get(keys::kLaunchWebURL, NULL)) {
      type_ = TYPE_HOSTED_APP;
    } else if (value_->Get(keys::kPlatformAppBackground, NULL)) {
      type_ = TYPE_PLATFORM_APP;
    } else {
      type_ = TYPE_LEGACY_PACKAGED_APP;
    }
  } else {
    type_ = TYPE_EXTENSION;
  }
  CHECK_NE(type_, TYPE_UNKNOWN);
}

Manifest::~Manifest() {
}

void Manifest::SetExtensionId(const ExtensionId& id) {
  extension_id_ = id;
  hashed_id_ = HashedExtensionId(id);
}

bool Manifest::ValidateManifest(
    std::string* error,
    std::vector<InstallWarning>* warnings) const {
  *error = "";

  // Check every feature to see if its in the manifest. Note that this means
  // we will ignore keys that are not features; we do this for forward
  // compatibility.
  // TODO(aa): Consider having an error here in the case of strict error
  // checking to let developers know when they screw up.

  const FeatureProvider* manifest_feature_provider =
      FeatureProvider::GetManifestFeatures();
  for (const auto& map_entry : manifest_feature_provider->GetAllFeatures()) {
    // Use Get instead of HasKey because the former uses path expansion.
    if (!value_->Get(map_entry.first, nullptr))
      continue;

    Feature::Availability result = map_entry.second->IsAvailableToManifest(
        hashed_id_, type_, location_, GetManifestVersion());
    if (!result.is_available())
      warnings->push_back(InstallWarning(result.message(), map_entry.first));
  }

  // Also generate warnings for keys that are not features.
  for (base::DictionaryValue::Iterator it(*value_); !it.IsAtEnd();
       it.Advance()) {
    if (!manifest_feature_provider->GetFeature(it.key())) {
      warnings->push_back(InstallWarning(
          ErrorUtils::FormatErrorMessage(
              manifest_errors::kUnrecognizedManifestKey, it.key()),
          it.key()));
    }
  }
  return true;
}

bool Manifest::HasKey(const std::string& key) const {
  return CanAccessKey(key) && value_->HasKey(key);
}

bool Manifest::HasPath(const std::string& path) const {
  base::Value* ignored = NULL;
  return CanAccessPath(path) && value_->Get(path, &ignored);
}

bool Manifest::Get(
    const std::string& path, const base::Value** out_value) const {
  return CanAccessPath(path) && value_->Get(path, out_value);
}

bool Manifest::GetBoolean(
    const std::string& path, bool* out_value) const {
  return CanAccessPath(path) && value_->GetBoolean(path, out_value);
}

bool Manifest::GetInteger(
    const std::string& path, int* out_value) const {
  return CanAccessPath(path) && value_->GetInteger(path, out_value);
}

bool Manifest::GetString(
    const std::string& path, std::string* out_value) const {
  return CanAccessPath(path) && value_->GetString(path, out_value);
}

bool Manifest::GetString(
    const std::string& path, base::string16* out_value) const {
  return CanAccessPath(path) && value_->GetString(path, out_value);
}

bool Manifest::GetDictionary(
    const std::string& path, const base::DictionaryValue** out_value) const {
  return CanAccessPath(path) && value_->GetDictionary(path, out_value);
}

bool Manifest::GetList(
    const std::string& path, const base::ListValue** out_value) const {
  return CanAccessPath(path) && value_->GetList(path, out_value);
}

Manifest* Manifest::DeepCopy() const {
  Manifest* manifest = new Manifest(
      location_, std::unique_ptr<base::DictionaryValue>(value_->DeepCopy()));
  manifest->SetExtensionId(extension_id_);
  return manifest;
}

bool Manifest::Equals(const Manifest* other) const {
  return other && value_->Equals(other->value());
}

int Manifest::GetManifestVersion() const {
  // Platform apps were launched after manifest version 2 was the preferred
  // version, so they default to that.
  int manifest_version = type_ == TYPE_PLATFORM_APP ? 2 : 1;
  value_->GetInteger(keys::kManifestVersion, &manifest_version);
  return manifest_version;
}

bool Manifest::CanAccessPath(const std::string& path) const {
  std::string key;
  for (const base::StringPiece& component : base::SplitStringPiece(
           path, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
    component.AppendToString(&key);
    if (!CanAccessKey(key))
      return false;
    key += '.';
  }
  return true;
}

bool Manifest::CanAccessKey(const std::string& key) const {
  const Feature* feature =
      FeatureProvider::GetManifestFeatures()->GetFeature(key);
  if (!feature)
    return true;

  return feature
      ->IsAvailableToManifest(hashed_id_, type_, location_,
                              GetManifestVersion())
      .is_available();
}

}  // namespace extensions
