// Copyright (c) 2012 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 REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_
#define REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/thread_task_runner_handle.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/var.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
#include "remoting/client/key_event_mapper.h"
#include "remoting/client/plugin/media_source_video_renderer.h"
#include "remoting/client/plugin/pepper_input_handler.h"
#include "remoting/client/plugin/pepper_plugin_thread_delegate.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/client_stub.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/connection_to_host.h"
#include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/input_event_tracker.h"
#include "remoting/protocol/mouse_input_filter.h"
#include "remoting/protocol/negotiating_client_authenticator.h"
#include "remoting/protocol/third_party_client_authenticator.h"

namespace base {
class DictionaryValue;
}  // namespace base

namespace pp {
class InputEvent;
class Module;
class VarDictionary;
}  // namespace pp

namespace jingle_glue {
class JingleThreadWrapper;
}  // namespace jingle_glue

namespace webrtc {
class DesktopRegion;
class DesktopSize;
class DesktopVector;
}  // namespace webrtc

namespace remoting {

class ChromotingClient;
class ChromotingStats;
class ClientContext;
class DelegatingSignalStrategy;
class FrameConsumer;
class FrameConsumerProxy;
class PepperAudioPlayer;
class TokenFetcherProxy;
class PepperView;
class RectangleUpdateDecoder;
class SignalStrategy;
class VideoRenderer;

struct ClientConfig;

class ChromotingInstance :
      public ClientUserInterface,
      public MediaSourceVideoRenderer::Delegate,
      public protocol::ClipboardStub,
      public protocol::CursorShapeStub,
      public pp::Instance {
 public:
  // Plugin API version. This should be incremented whenever the API
  // interface changes.
  static const int kApiVersion = 7;

  // Plugin API features. This allows orthogonal features to be supported
  // without bumping the API version.
  static const char kApiFeatures[];

  // Capabilities supported by the plugin that should also be supported by the
  // webapp to be enabled.
  static const char kRequestedCapabilities[];

  // Capabilities supported by the plugin that do not need to be supported by
  // the webapp to be enabled.
  static const char kSupportedCapabilities[];

  // Backward-compatibility version used by for the messaging
  // interface. Should be updated whenever we remove support for
  // an older version of the API.
  static const int kApiMinMessagingVersion = 5;

  // Backward-compatibility version used by for the ScriptableObject
  // interface. Should be updated whenever we remove support for
  // an older version of the API.
  static const int kApiMinScriptableVersion = 5;

  // Helper method to parse authentication_methods parameter.
  static bool ParseAuthMethods(const std::string& auth_methods,
                               ClientConfig* config);

  explicit ChromotingInstance(PP_Instance instance);
  virtual ~ChromotingInstance();

  // pp::Instance interface.
  virtual void DidChangeFocus(bool has_focus) OVERRIDE;
  virtual void DidChangeView(const pp::View& view) OVERRIDE;
  virtual bool Init(uint32_t argc, const char* argn[],
                    const char* argv[]) OVERRIDE;
  virtual void HandleMessage(const pp::Var& message) OVERRIDE;
  virtual bool HandleInputEvent(const pp::InputEvent& event) OVERRIDE;

  // ClientUserInterface interface.
  virtual void OnConnectionState(protocol::ConnectionToHost::State state,
                                 protocol::ErrorCode error) OVERRIDE;
  virtual void OnConnectionReady(bool ready) OVERRIDE;
  virtual void OnRouteChanged(const std::string& channel_name,
                              const protocol::TransportRoute& route) OVERRIDE;
  virtual void SetCapabilities(const std::string& capabilities) OVERRIDE;
  virtual void SetPairingResponse(
      const protocol::PairingResponse& pairing_response) OVERRIDE;
  virtual void DeliverHostMessage(
      const protocol::ExtensionMessage& message) OVERRIDE;
  virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE;
  virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE;
  virtual scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher>
  GetTokenFetcher(const std::string& host_public_key) OVERRIDE;

  // protocol::ClipboardStub interface.
  virtual void InjectClipboardEvent(
      const protocol::ClipboardEvent& event) OVERRIDE;

  // protocol::CursorShapeStub interface.
  virtual void SetCursorShape(
      const protocol::CursorShapeInfo& cursor_shape) OVERRIDE;

  // Called by PepperView.
  void SetDesktopSize(const webrtc::DesktopSize& size,
                      const webrtc::DesktopVector& dpi);
  void SetDesktopShape(const webrtc::DesktopRegion& shape);
  void OnFirstFrameReceived();

  // Return statistics record by ChromotingClient.
  // If no connection is currently active then NULL will be returned.
  ChromotingStats* GetStats();

  // Registers a global log message handler that redirects the log output to
  // our plugin instance.
  // This is called by the plugin's PPP_InitializeModule.
  // Note that no logging will be processed unless a ChromotingInstance has been
  // registered for logging (see RegisterLoggingInstance).
  static void RegisterLogMessageHandler();

  // Registers this instance so it processes messages sent by the global log
  // message handler. This overwrites any previously registered instance.
  void RegisterLoggingInstance();

  // Unregisters this instance so that debug log messages will no longer be sent
  // to it. If this instance is not the currently registered logging instance,
  // then the currently registered instance will stay in effect.
  void UnregisterLoggingInstance();

  // A Log Message Handler that is called after each LOG message has been
  // processed. This must be of type LogMessageHandlerFunction defined in
  // base/logging.h.
  static bool LogToUI(int severity, const char* file, int line,
                      size_t message_start, const std::string& str);

  // Requests the webapp to fetch a third-party token.
  void FetchThirdPartyToken(
      const GURL& token_url,
      const std::string& host_public_key,
      const std::string& scope,
      const base::WeakPtr<TokenFetcherProxy> pepper_token_fetcher);

 private:
  FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);

  // Used as the |FetchSecretCallback| for IT2Me (or Me2Me from old webapps).
  // Immediately calls |secret_fetched_callback| with |shared_secret|.
  static void FetchSecretFromString(
      const std::string& shared_secret,
      bool pairing_supported,
      const protocol::SecretFetchedCallback& secret_fetched_callback);

  // Message handlers for messages that come from JavaScript. Called
  // from HandleMessage().
  void HandleConnect(const base::DictionaryValue& data);
  void HandleDisconnect(const base::DictionaryValue& data);
  void HandleOnIncomingIq(const base::DictionaryValue& data);
  void HandleReleaseAllKeys(const base::DictionaryValue& data);
  void HandleInjectKeyEvent(const base::DictionaryValue& data);
  void HandleRemapKey(const base::DictionaryValue& data);
  void HandleTrapKey(const base::DictionaryValue& data);
  void HandleSendClipboardItem(const base::DictionaryValue& data);
  void HandleNotifyClientResolution(const base::DictionaryValue& data);
  void HandlePauseVideo(const base::DictionaryValue& data);
  void HandleVideoControl(const base::DictionaryValue& data);
  void HandlePauseAudio(const base::DictionaryValue& data);
  void HandleOnPinFetched(const base::DictionaryValue& data);
  void HandleOnThirdPartyTokenFetched(const base::DictionaryValue& data);
  void HandleRequestPairing(const base::DictionaryValue& data);
  void HandleExtensionMessage(const base::DictionaryValue& data);
  void HandleAllowMouseLockMessage();
  void HandleEnableMediaSourceRendering();
  void HandleSendMouseInputWhenUnfocused();
  void HandleDelegateLargeCursors();

  // Helper method called from Connect() to connect with parsed config.
  void ConnectWithConfig(const ClientConfig& config,
                         const std::string& local_jid);

  // Helper method to post messages to the webapp.
  void PostChromotingMessage(const std::string& method,
                             const pp::VarDictionary& data);

  // Same as above, but serializes messages to JSON before sending them.  This
  // method is used for backward compatibility with older version of the webapp
  // that expect to received most messages formatted using JSON.
  //
  // TODO(sergeyu): When all current versions of the webapp support raw messages
  // remove this method and use PostChromotingMessage() instead.
  void PostLegacyJsonMessage(const std::string& method,
                       scoped_ptr<base::DictionaryValue> data);

  // Posts trapped keys to the web-app to handle.
  void SendTrappedKey(uint32 usb_keycode, bool pressed);

  // Callback for DelegatingSignalStrategy.
  void SendOutgoingIq(const std::string& iq);

  void SendPerfStats();

  void ProcessLogToUI(const std::string& message);

  // Returns true if the hosting content has the chrome-extension:// scheme.
  bool IsCallerAppOrExtension();

  // Returns true if there is a ConnectionToHost and it is connected.
  bool IsConnected();

  // Used as the |FetchSecretCallback| for Me2Me connections.
  // Uses the PIN request dialog in the webapp to obtain the shared secret.
  void FetchSecretFromDialog(
      bool pairing_supported,
      const protocol::SecretFetchedCallback& secret_fetched_callback);

  // MediaSourceVideoRenderer::Delegate implementation.
  virtual void OnMediaSourceSize(const webrtc::DesktopSize& size,
                                 const webrtc::DesktopVector& dpi) OVERRIDE;
  virtual void OnMediaSourceShape(const webrtc::DesktopRegion& shape) OVERRIDE;
  virtual void OnMediaSourceReset(const std::string& format) OVERRIDE;
  virtual void OnMediaSourceData(uint8_t* buffer, size_t buffer_size,
                                 bool keyframe) OVERRIDE;

  bool initialized_;

  PepperPluginThreadDelegate plugin_thread_delegate_;
  scoped_refptr<PluginThreadTaskRunner> plugin_task_runner_;
  scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
  scoped_ptr<jingle_glue::JingleThreadWrapper> thread_wrapper_;
  ClientContext context_;
  scoped_ptr<VideoRenderer> video_renderer_;
  scoped_ptr<PepperView> view_;
  scoped_ptr<base::WeakPtrFactory<FrameConsumer> > view_weak_factory_;
  pp::View plugin_view_;

  // Contains the most-recently-reported desktop shape, if any.
  scoped_ptr<webrtc::DesktopRegion> desktop_shape_;

  scoped_ptr<DelegatingSignalStrategy> signal_strategy_;

  scoped_ptr<protocol::ConnectionToHost> host_connection_;
  scoped_ptr<ChromotingClient> client_;

  // Input pipeline components, in reverse order of distance from input source.
  protocol::MouseInputFilter mouse_input_filter_;
  protocol::InputEventTracker input_tracker_;
  KeyEventMapper key_mapper_;
  scoped_ptr<protocol::InputFilter> normalizing_input_filter_;
  PepperInputHandler input_handler_;

  // PIN Fetcher.
  bool use_async_pin_dialog_;
  protocol::SecretFetchedCallback secret_fetched_callback_;

  // Set to true if the webapp has requested to use MediaSource API for
  // rendering. In that case all the encoded video will be passed to the
  // webapp for decoding.
  bool use_media_source_rendering_;

  // Set to true if the web-app can handle large cursors. If false, then large
  // cursors will be cropped to the maximum size supported by Pepper.
  bool delegate_large_cursors_;

  base::WeakPtr<TokenFetcherProxy> token_fetcher_proxy_;

  // Weak reference to this instance, used for global logging and task posting.
  base::WeakPtrFactory<ChromotingInstance> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ChromotingInstance);
};

}  // namespace remoting

#endif  // REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_
