// Copyright (c) 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.

#ifndef EXTENSIONS_COMMON_MANIFEST_HANDLER_H_
#define EXTENSIONS_COMMON_MANIFEST_HANDLER_H_

#include <set>
#include <string>
#include <vector>

#include "base/lazy_instance.h"
#include "base/memory/linked_ptr.h"
#include "base/strings/string16.h"
#include "extensions/common/manifest.h"

namespace extensions {
class Extension;
class ManifestPermission;
class ManifestPermissionSet;

// An interface for clients that recognize and parse keys in extension
// manifests.
class ManifestHandler {
 public:
  ManifestHandler();
  virtual ~ManifestHandler();

  // Attempts to parse the extension's manifest.
  // Returns true on success or false on failure; if false, |error| will
  // be set to a failure message.
  virtual bool Parse(Extension* extension, base::string16* error) = 0;

  // Validate that files associated with this manifest key exist.
  // Validation takes place after parsing. May also append a series of
  // warning messages to |warnings|.
  //
  // Otherwise, returns false, and a description of the error is
  // returned in |error|.
  // TODO(yoz): Change error to base::string16. See crbug.com/71980.
  virtual bool Validate(const Extension* extension,
                        std::string* error,
                        std::vector<InstallWarning>* warnings) const;

  // If false (the default), only parse the manifest if a registered
  // key is present in the manifest. If true, always attempt to parse
  // the manifest for this extension type, even if no registered keys
  // are present. This allows specifying a default parsed value for
  // extensions that don't declare our key in the manifest.
  // TODO(yoz): Use Feature availability instead.
  virtual bool AlwaysParseForType(Manifest::Type type) const;

  // Same as AlwaysParseForType, but for Validate instead of Parse.
  virtual bool AlwaysValidateForType(Manifest::Type type) const;

  // The list of keys that, if present, should be parsed before calling our
  // Parse (typically, because our Parse needs to read those keys).
  // Defaults to empty.
  virtual const std::vector<std::string> PrerequisiteKeys() const;

  // Associate us with our keys() in the manifest. A handler can register
  // for multiple keys. The global registry takes ownership of this;
  // if it has an existing handler for |key|, it replaces it with this.
  // Manifest handlers must be registered at process startup in
  // common_manifest_handlers.cc or chrome_manifest_handlers.cc:
  // (new MyManifestHandler)->Register();
  void Register();

  // Creates a |ManifestPermission| instance for the given manifest key |name|.
  // The returned permission does not contain any permission data, so this
  // method is usually used before calling |FromValue| or |Read|. Returns
  // |NULL| if the manifest handler does not support custom permissions.
  virtual ManifestPermission* CreatePermission();

  // Creates a |ManifestPermission| instance containing the initial set of
  // required manifest permissions for the given |extension|. Returns |NULL| if
  // the manifest handler does not support custom permissions or if there was
  // no manifest key in the extension manifest for this handler.
  virtual ManifestPermission* CreateInitialRequiredPermission(
      const Extension* extension);

  // Calling FinalizeRegistration indicates that there are no more
  // manifest handlers to be registered.
  static void FinalizeRegistration();

  static bool IsRegistrationFinalized();

  // Call Parse on all registered manifest handlers that should parse
  // this extension.
  static bool ParseExtension(Extension* extension, base::string16* error);

  // Call Validate on all registered manifest handlers for this extension.
  static bool ValidateExtension(const Extension* extension,
                                std::string* error,
                                std::vector<InstallWarning>* warnings);

  // Calls |CreatePermission| on the manifest handler for |key|. Returns |NULL|
  // if there is no manifest handler for |key| or if the manifest handler for
  // |key| does not support custom permissions.
  static ManifestPermission* CreatePermission(const std::string& key);

  // Calls |CreateInitialRequiredPermission| on all registered manifest handlers
  // and adds the returned permissions to |permission_set|. Note this should be
  // called after all manifest data elements have been read, parsed and stored
  // in the manifest data property of |extension|, as manifest handlers need
  // access to their manifest data to initialize their required manifest
  // permission.
  static void AddExtensionInitialRequiredPermissions(
      const Extension* extension, ManifestPermissionSet* permission_set);

 protected:
  // A convenience method for handlers that only register for 1 key,
  // so that they can define keys() { return SingleKey(kKey); }
  static const std::vector<std::string> SingleKey(const std::string& key);

 private:
  // The keys to register us for (in Register).
  virtual const std::vector<std::string> Keys() const = 0;
};

// The global registry for manifest handlers.
class ManifestHandlerRegistry {
 private:
  friend class ManifestHandler;
  friend class ScopedTestingManifestHandlerRegistry;
  friend struct base::DefaultLazyInstanceTraits<ManifestHandlerRegistry>;

  ManifestHandlerRegistry();
  ~ManifestHandlerRegistry();

  void Finalize();

  void RegisterManifestHandler(const std::string& key,
                               linked_ptr<ManifestHandler> handler);
  bool ParseExtension(Extension* extension, base::string16* error);
  bool ValidateExtension(const Extension* extension,
                         std::string* error,
                         std::vector<InstallWarning>* warnings);

  ManifestPermission* CreatePermission(const std::string& key);

  void AddExtensionInitialRequiredPermissions(
      const Extension* extension,
      ManifestPermissionSet* permission_set);

  // Overrides the current global ManifestHandlerRegistry with
  // |registry|, returning the current one.
  static ManifestHandlerRegistry* SetForTesting(
      ManifestHandlerRegistry* new_registry);

  typedef std::map<std::string, linked_ptr<ManifestHandler> >
      ManifestHandlerMap;
  typedef std::map<ManifestHandler*, int> ManifestHandlerPriorityMap;

  // Puts the manifest handlers in order such that each handler comes after
  // any handlers for their PrerequisiteKeys. If there is no handler for
  // a prerequisite key, that dependency is simply ignored.
  // CHECKs that there are no manifest handlers with circular dependencies.
  void SortManifestHandlers();

  // All registered manifest handlers.
  ManifestHandlerMap handlers_;

  // The priority for each manifest handler. Handlers with lower priority
  // values are evaluated first.
  ManifestHandlerPriorityMap priority_map_;

  bool is_finalized_;
};

}  // namespace extensions

#endif  // EXTENSIONS_COMMON_MANIFEST_HANDLER_H_
