/*
 * Copyright 2015 Google Inc. 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_DEBUG_HUB_H_
#define COBALT_DEBUG_DEBUG_HUB_H_

#if defined(ENABLE_DEBUG_CONSOLE)

#include <list>
#include <map>
#include <string>

#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "cobalt/base/log_message_handler.h"
#include "cobalt/base/source_location.h"
#include "cobalt/debug/debugger.h"
#include "cobalt/script/callback_function.h"
#include "cobalt/script/script_object.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace debug {

// This class implements an interface to JavaScript for debugging.
// The public methods of this class are expected to be exposed in DebugHub.idl.
// The main (and typically only) JavaScript client is the debug console.
// A stub implementation is used if ENABLE_DEBUG_CONSOLE is not defined.
//
// Log messages generated by the app via LOG are sent to the client
// via a JavaScript callback registered with SetLogMessageCallback.
// This typically includes console output from the main web module.
//
// The JavaScript client can examine the available list of registered console
// values.
//
// There is a debugger client available via the |debugger_| member that can
// connect to the debug server attached to the main web module. The debug
// console uses this to send debugging commands and receive debugging events.
// The debug server is accessed using the |get_debug_server_callback|
// parameter specified in the constructor.
//
// The JavaScript client can send arbitrary messages to an object of this class
// on a specific named channel using the SendCommand method. These messages are
// forwarded to any component of the app that registers a message handler for
// that channel by creating an instance of a class derived from CommandHandler.

class DebugHub : public script::Wrappable {
 public:
  // Type for log message callback on JS side.
  typedef script::CallbackFunction<
      void(int severity, const std::string& file, int line,
           size_t message_start, const std::string& msg)> LogMessageCallback;
  typedef script::ScriptObject<LogMessageCallback> LogMessageCallbackArg;

  // Function signature to call when we need to query for the Hud visibility
  // mode.
  typedef base::Callback<int()> GetHudModeCallback;

  // 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;

  // Declare logging levels here for export to JS
  static const int kLogInfo = logging::LOG_INFO;
  static const int kLogWarning = logging::LOG_WARNING;
  static const int kLogError = logging::LOG_ERROR;
  static const int kLogErrorReport = logging::LOG_ERROR_REPORT;
  static const int kLogFatal = logging::LOG_FATAL;

  DebugHub(const GetHudModeCallback& get_hud_mode_callback,
           const Debugger::GetDebugServerCallback& get_debug_server_callback);
  ~DebugHub();

  // Gets the JavaScript debugger client interface.
  const scoped_refptr<Debugger>& debugger() { return debugger_; }

  // Called from JS to set the log message callback.
  // Must be called from |message_loop_|.
  void SetLogMessageCallback(const LogMessageCallbackArg& callback);

  // Gets the collection of available CVal names as an alphabetically ordered,
  // space-separated list.
  std::string GetConsoleValueNames() const;

  // Gets the value of a named CVal as a pretty string.
  std::string GetConsoleValue(const std::string& name) const;

  int GetDebugConsoleMode() const;

  // Gets the collection of registered command channels as an alphabetically
  // ordered, space-separated list.
  std::string GetCommandChannels() const;

  // Gets the help strings for a specified command channel.
  std::string GetCommandChannelShortHelp(const std::string& channel) const;
  std::string GetCommandChannelLongHelp(const std::string& channel) const;

  // Sends a command to be handled by registered handers.
  // This lets the JavaScript debug console trigger actions in the app.
  void SendCommand(const std::string& channel, const std::string& message);

  DEFINE_WRAPPABLE_TYPE(DebugHub);

 private:
  // Called by LogMessageHandler for each log message.
  // May be called from any thread.
  bool OnLogMessage(int severity, const char* file, int line,
                    size_t message_start, const std::string& str);

  // Forwards a log message to |log_message_callback|.
  // Must be called on |message_loop_|.
  void OnLogMessageInternal(int severity, const char* file, int line,
                            size_t message_start, const std::string& str);

  // The message loop this object was constructed on, which should be the
  // same as the WebModule this object is attached to.
  MessageLoop* message_loop_;

  // A function that we can call to query the Hud visibility mode.
  const GetHudModeCallback get_hud_mode_callback_;

  // The JavaScript callback to forward log messages to.
  base::LogMessageHandler::CallbackId log_message_handler_callback_id_;

  // Interface to the JavaScript debugger client.
  scoped_refptr<Debugger> debugger_;

  // Use a weak pointer when posting |OnLogMessageInternal| tasks.
  base::WeakPtrFactory<DebugHub> weak_ptr_factory_;
  base::WeakPtr<DebugHub> weak_ptr_;

  // Used to ensure we don't run the log message callback recursively.
  bool is_logging_;

  scoped_ptr<LogMessageCallbackArg::Reference> log_message_callback_;
};

}  // namespace debug
}  // namespace cobalt

#endif  // ENABLE_DEBUG_CONSOLE
#endif  // COBALT_DEBUG_DEBUG_HUB_H_
