// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_DEBUG_CONSOLE_DEBUG_HUB_H_
#define COBALT_DEBUG_CONSOLE_DEBUG_HUB_H_

#include <string>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/optional.h"
#include "cobalt/debug/console/console_command.h"
#include "cobalt/debug/console/debugger_event_target.h"
#include "cobalt/debug/debug_client.h"
#include "cobalt/dom/c_val_view.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace debug {
namespace console {

// This class implements an interface to JavaScript for debugging.
// The main (and typically only) JavaScript client is the debug console.
//
// This is modeled after chrome.debugger extension API.
// https://developer.chrome.com/extensions/debugger
class DebugHub : public script::Wrappable, public DebugClient::Delegate {
 public:
  // Function signature to call when we need to query for the Hud visibility
  // mode.
  typedef base::Callback<int()> GetHudModeCallback;

  // JavaScript callback to be run when debugger attaches/detaches.
  typedef script::CallbackFunction<void()> AttachCallback;
  typedef script::ScriptValue<AttachCallback> AttachCallbackArg;

  // JavaScript callback to receive the response after executing a command.
  typedef script::CallbackFunction<void(base::optional<std::string>)>
      ResponseCallback;
  typedef script::ScriptValue<ResponseCallback> ResponseCallbackArg;

  // Debug console visibility modes.
  static const int kDebugConsoleOff = 0;
  static const int kDebugConsoleHud = 1;
  static const int kDebugConsoleOn = 2;
  static const int kDebugConsoleNumModes = kDebugConsoleOn + 1;

  // Thread-safe ref-counted struct used to pass asynchronously executed
  // response callbacks around. Stores the message loop the callback must be
  // executed on as well as the callback itself.
  struct ResponseCallbackInfo
      : public base::RefCountedThreadSafe<ResponseCallbackInfo> {
    ResponseCallbackInfo(DebugHub* const debugger,
                         const ResponseCallbackArg& cb)
        : callback(debugger, cb),
          message_loop_proxy(base::MessageLoopProxy::current()) {}
    ResponseCallbackArg::Reference callback;
    scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
    friend class base::RefCountedThreadSafe<ResponseCallbackInfo>;
  };

  DebugHub(const GetHudModeCallback& get_hud_mode_callback,
           const CreateDebugClientCallback& create_debug_client_callback);
  ~DebugHub();

  const scoped_refptr<dom::CValView>& c_val() const { return c_val_; }

  int GetDebugConsoleMode() const;

  void Attach(const AttachCallbackArg& callback);
  void Detach(const AttachCallbackArg& callback);

  // Sends a devtools protocol command to be executed in the context of the main
  // WebModule that is being debugged.
  void SendCommand(const std::string& method, const std::string& json_params,
                   const ResponseCallbackArg& callback);

  const base::optional<std::string>& last_error() const { return last_error_; }
  const scoped_refptr<DebuggerEventTarget>& on_event() const {
    return on_event_;
  }

  const script::Sequence<ConsoleCommand> console_commands() const;

  // Sends a console command to be handled in the context of the debug WebModule
  // by a registered hander. This lets the JavaScript debug console trigger
  // actions in the app.
  void SendConsoleCommand(const std::string& command,
                          const std::string& message);

  DEFINE_WRAPPABLE_TYPE(DebugHub);
  void TraceMembers(script::Tracer* tracer) override;

 protected:
  // Called by the debug dispatcher with the response of a command on the
  // message loop the command was sent from (the message loop of this object).
  // Passes the response to the JavaScript callback registered with the command.
  void OnCommandResponse(
      const scoped_refptr<ResponseCallbackInfo>& callback_info,
      const base::optional<std::string>& response) const;

  // DebugClient::Delegate implementation.
  void OnDebugClientEvent(
      const std::string& method,
      const base::optional<std::string>& json_params) override;
  void OnDebugClientDetach(const std::string& reason) override;

 private:
  // Runs a script response callback with the specified response.
  // Should be called from the same message loop as the script command that it
  // is a response for.
  void RunResponseCallback(
      const scoped_refptr<ResponseCallbackInfo>& callback_info,
      base::optional<std::string> response) const;

  // A view onto Cobalt's CVals
  scoped_refptr<dom::CValView> c_val_;

  // A function to query the Hud visibility mode.
  const GetHudModeCallback get_hud_mode_callback_;

  // A factory function to create a debug client.
  const CreateDebugClientCallback create_debug_client_callback_;

  // Handler for debugger events.
  scoped_refptr<DebuggerEventTarget> on_event_;

  // Debug client that connects to the dispatcher.
  scoped_ptr<DebugClient> debug_client_;

  // This will be defined if there was an error since the last operation.
  // TODO: Chrome implements similar functionality throughout the
  // app using the chrome.runtime.lastError object. When we add support for
  // Cobalt's equivalent to the runtime extension API, we may wish to consider
  // using that and removing this attribute.
  base::optional<std::string> last_error_;
};

}  // namespace console
}  // namespace debug
}  // namespace cobalt

#endif  // COBALT_DEBUG_CONSOLE_DEBUG_HUB_H_
