// Copyright 2016 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_BACKEND_DEBUG_MODULE_H_
#define COBALT_DEBUG_BACKEND_DEBUG_MODULE_H_

#include <memory>
#include <string>
#include <utility>

#include "base/message_loop/message_loop.h"
#include "cobalt/base/debugger_hooks.h"
#include "cobalt/debug/backend/cobalt_agent.h"
#include "cobalt/debug/backend/css_agent.h"
#include "cobalt/debug/backend/debug_backend.h"
#include "cobalt/debug/backend/debug_dispatcher.h"
#include "cobalt/debug/backend/debug_script_runner.h"
#include "cobalt/debug/backend/debugger_hooks_impl.h"
#include "cobalt/debug/backend/debugger_state.h"
#include "cobalt/debug/backend/dom_agent.h"
#include "cobalt/debug/backend/log_agent.h"
#include "cobalt/debug/backend/overlay_agent.h"
#include "cobalt/debug/backend/page_agent.h"
#include "cobalt/debug/backend/render_overlay.h"
#include "cobalt/debug/backend/script_debugger_agent.h"
#include "cobalt/debug/backend/tracing_controller.h"
#include "cobalt/debug/json_object.h"
#include "cobalt/dom/window.h"
#include "cobalt/render_tree/resource_provider.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/script_debugger.h"

namespace cobalt {
namespace debug {
namespace backend {

// A container for a DebugDispatcher and all the agents that implement debugging
// protocol domains. This class is not intended to provide any functionality of
// its own beyond access to the DebugDispatcher member, which provides the
// interface to send commands specified by the debugging protocol:
// https://chromedevtools.github.io/devtools-protocol/1-3
class DebugModule : public script::ScriptDebugger::Delegate {
 public:
  // Construct the debug dispatcher on the current message loop.
  DebugModule(DebuggerHooksImpl* debugger_hooks,
              script::GlobalEnvironment* global_environment,
              RenderOverlay* render_overlay,
              render_tree::ResourceProvider* resource_provider,
              dom::Window* window, DebuggerState* debugger_state);

  // Construct the debug dispatcher on the specified message loop.
  DebugModule(DebuggerHooksImpl* debugger_hooks,
              script::GlobalEnvironment* global_environment,
              RenderOverlay* render_overlay,
              render_tree::ResourceProvider* resource_provider,
              dom::Window* window, DebuggerState* debugger_state,
              base::MessageLoop* message_loop);

  virtual ~DebugModule();

  DebugDispatcher* debug_dispatcher() const { return debug_dispatcher_.get(); }

  // Shutdown this instance of the debugger before navigation and return its
  // state so that it can be restored in the new |DebugModule| after navigation.
  // This instance of the debugger is no longer usable after calling this
  // method, with the expectation is that it will soon be deleted with its
  // owning WebModule.
  std::unique_ptr<DebuggerState> Freeze();

 private:
  // Data used to construct an instance of this class that does not need to be
  // persisted.
  struct ConstructionData {
    ConstructionData(DebuggerHooksImpl* debugger_hooks,
                     script::GlobalEnvironment* global_environment,
                     base::MessageLoop* message_loop,
                     RenderOverlay* render_overlay,
                     render_tree::ResourceProvider* resource_provider,
                     dom::Window* window, DebuggerState* debugger_state)
        : debugger_hooks(debugger_hooks),
          global_environment(global_environment),
          message_loop(message_loop),
          render_overlay(render_overlay),
          resource_provider(resource_provider),
          window(window),
          debugger_state(debugger_state) {}

    DebuggerHooksImpl* debugger_hooks;
    script::GlobalEnvironment* global_environment;
    base::MessageLoop* message_loop;
    RenderOverlay* render_overlay;
    render_tree::ResourceProvider* resource_provider;
    dom::Window* window;
    DebuggerState* debugger_state;
  };

  // Builds |debug_dispatcher_| on |message_loop_| by calling |BuildInternal|,
  // posting the task and waiting for it if necessary.
  void Build(const ConstructionData& data);

  // Signals |created| when done, if not NULL.
  void BuildInternal(const ConstructionData& data);

  // Sends a protocol event to the frontend through |DebugDispatcher|.
  void SendEvent(const std::string& method, const std::string& params);

  // script::ScriptDebugger::Delegate implementation.
  void OnScriptDebuggerPause() override;
  void OnScriptDebuggerResume() override;
  void OnScriptDebuggerResponse(const std::string& response) override;
  void OnScriptDebuggerEvent(const std::string& event) override;

  bool is_frozen_ = true;

  DebuggerHooksImpl* debugger_hooks_ = nullptr;

  // Handles all debugging interaction with the JavaScript engine.
  std::unique_ptr<script::ScriptDebugger> script_debugger_;

  // Runs backend JavaScript.
  std::unique_ptr<DebugScriptRunner> script_runner_;

  // Handles routing of commands, responses and event notifications.
  std::unique_ptr<DebugDispatcher> debug_dispatcher_;

  // Wrappable object providing native helpers for backend JavaScript.
  scoped_refptr<DebugBackend> debug_backend_;
  std::unique_ptr<CobaltAgent> cobalt_agent_;
  std::unique_ptr<LogAgent> log_agent_;
  std::unique_ptr<DOMAgent> dom_agent_;
  scoped_refptr<CSSAgent> css_agent_;
  std::unique_ptr<OverlayAgent> overlay_agent_;
  std::unique_ptr<PageAgent> page_agent_;
  std::unique_ptr<ScriptDebuggerAgent> script_debugger_agent_;
  std::unique_ptr<TracingController> tracing_controller_;
};

}  // namespace backend
}  // namespace debug
}  // namespace cobalt

#endif  // COBALT_DEBUG_BACKEND_DEBUG_MODULE_H_
