// Copyright 2016 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_RENDERER_NATIVE_EXTENSION_BINDINGS_SYSTEM_H_
#define EXTENSIONS_RENDERER_NATIVE_EXTENSION_BINDINGS_SYSTEM_H_

#include <memory>
#include <string>

#include "base/memory/weak_ptr.h"
#include "extensions/renderer/bindings/api_binding_types.h"
#include "extensions/renderer/bindings/api_bindings_system.h"
#include "extensions/renderer/bindings/event_emitter.h"
#include "extensions/renderer/feature_cache.h"
#include "extensions/renderer/native_renderer_messaging_service.h"
#include "v8/include/v8.h"

namespace extensions {
class IPCMessageSender;
class RequestSender;
class ScriptContext;

// The class responsible for creating extension bindings in different contexts,
// permissions/availability checks, dispatching requests and handling responses,
// and dispatching events to listeners.
// This is designed to be used on a single thread (and for all contexts on that
// thread), but should be safe to use on threads other than the main thread (so
// that worker threads can have extension bindings).
// TODO(devlin): Rename this to be simply "ExtensionBindingsSystem"? There's
// no non-native version, but the rename causes churn and also makes git history
// a bit messy (since there used to be a different ExtensionBindingsSystem).
class NativeExtensionBindingsSystem {
 public:
  explicit NativeExtensionBindingsSystem(
      std::unique_ptr<IPCMessageSender> ipc_message_sender);
  ~NativeExtensionBindingsSystem();

  // Called when a new ScriptContext is created.
  void DidCreateScriptContext(ScriptContext* context);

  // Called when a ScriptContext is about to be released.
  void WillReleaseScriptContext(ScriptContext* context);

  // Updates the bindings for a given |context|. This happens at initialization,
  // but also when e.g. an extension gets updated permissions.
  void UpdateBindingsForContext(ScriptContext* context);

  // Dispatches an event with the given |name|, |event_args|, and
  // |filtering_info| in the given |context|.
  void DispatchEventInContext(const std::string& event_name,
                              const base::ListValue* event_args,
                              const EventFilteringInfo* filtering_info,
                              ScriptContext* context);

  // Returns true if there is a listener for the given |event_name| in the
  // associated |context|.
  bool HasEventListenerInContext(const std::string& event_name,
                                 ScriptContext* context);

  // Handles the response associated with the given |request_id|.
  void HandleResponse(int request_id,
                      bool success,
                      const base::ListValue& response,
                      const std::string& error);

  // Returns the associated RequestSender, if any.
  // TODO(devlin): Factor this out.
  RequestSender* GetRequestSender();

  // Returns the associated IPC message sender.
  IPCMessageSender* GetIPCMessageSender();

  // Called when an extension's permissions are updated.
  void OnExtensionPermissionsUpdated(const ExtensionId& id);

  // Called when an extension is removed.
  void OnExtensionRemoved(const ExtensionId& id);

  APIBindingsSystem* api_system() { return &api_system_; }
  NativeRendererMessagingService* messaging_service() {
    return &messaging_service_;
  }

  // Returns the API with the given |name| for the given |context|. Used for
  // testing purposes.
  v8::Local<v8::Object> GetAPIObjectForTesting(ScriptContext* context,
                                               const std::string& api_name);

 private:
  // Handles sending a given |request|, forwarding it on to the send_ipc_ after
  // adding additional info.
  void SendRequest(std::unique_ptr<APIRequestHandler::Request> request,
                   v8::Local<v8::Context> context);

  // Returns the transient user activation state for the |context|.
  bool GetUserActivationState(v8::Local<v8::Context> context);

  // Called when listeners for a given event have changed, and forwards it along
  // to |send_event_listener_ipc_|.
  void OnEventListenerChanged(const std::string& event_name,
                              binding::EventListenersChanged change,
                              const base::DictionaryValue* filter,
                              bool was_manual,
                              v8::Local<v8::Context> context);

  // Getter callback for an extension API, since APIs are constructed lazily.
  static void BindingAccessor(v8::Local<v8::Name> name,
                              const v8::PropertyCallbackInfo<v8::Value>& info);

  // Creates and returns the API binding for the given |name|.
  static v8::Local<v8::Object> GetAPIHelper(v8::Local<v8::Context> context,
                                            v8::Local<v8::String> name);

  // Gets the chrome.runtime API binding.
  static v8::Local<v8::Object> GetLastErrorParents(
      v8::Local<v8::Context> context,
      v8::Local<v8::Object>* secondary_parent);

  // Callback to get an API binding for an internal API.
  static void GetInternalAPI(const v8::FunctionCallbackInfo<v8::Value>& info);

  // Helper method to get a APIBindingJSUtil object for the current context,
  // and populate |binding_util_out|. We use an out parameter instead of
  // returning it in order to let us use weak ptrs, which can't be used on a
  // method with a return value.
  void GetJSBindingUtil(v8::Local<v8::Context> context,
                        v8::Local<v8::Value>* binding_util_out);

  std::unique_ptr<IPCMessageSender> ipc_message_sender_;

  // The APIBindingsSystem associated with this class.
  APIBindingsSystem api_system_;

  NativeRendererMessagingService messaging_service_;

  FeatureCache feature_cache_;

  // A function to acquire an internal API.
  v8::Eternal<v8::FunctionTemplate> get_internal_api_;

  base::WeakPtrFactory<NativeExtensionBindingsSystem> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(NativeExtensionBindingsSystem);
};

}  // namespace extensions

#endif  // EXTENSIONS_RENDERER_NATIVE_EXTENSION_BINDINGS_SYSTEM_H_
