// 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_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_value.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::ScriptValue<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);
  void TraceMembers(script::Tracer* tracer) override;

 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_
