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

#include <memory>

#include "cobalt/debug/backend/debug_module.h"

#include "cobalt/debug/backend/render_layer.h"

namespace cobalt {
namespace debug {
namespace backend {

namespace {
constexpr char kScriptDebuggerAgent[] = "ScriptDebuggerAgent";
constexpr char kConsoleAgent[] = "ConsoleAgent";
constexpr char kLogAgent[] = "LogAgent";
constexpr char kDomAgent[] = "DomAgent";
constexpr char kCssAgent[] = "CssAgent";
constexpr char kPageAgent[] = "PageAgent";
constexpr char kTracingAgent[] = "TracingAgent";

// Move the state for a particular agent out of the dictionary holding the
// state for all agents. Returns a NULL JSONObject if either |agents_state| is
// NULL or it doesn't hold a state for the agent.
JSONObject RemoveAgentState(const std::string& agent_name,
                            base::DictionaryValue* state_dict) {
  if (state_dict == nullptr) {
    return JSONObject();
  }

  std::unique_ptr<base::Value> value;
  if (!state_dict->Remove(agent_name, &value)) {
    return JSONObject();
  }

  std::unique_ptr<base::DictionaryValue> dictionary_value =
      base::DictionaryValue::From(std::move(value));
  if (!dictionary_value) {
    DLOG(ERROR) << "Unexpected state type for " << agent_name;
    return JSONObject();
  }

  return dictionary_value;
}

void StoreAgentState(base::DictionaryValue* state_dict,
                     const std::string& agent_name, JSONObject agent_state) {
  if (agent_state) {
    state_dict->Set(agent_name,
                    std::unique_ptr<base::Value>(agent_state.release()));
  }
}

}  // namespace

DebugModule::DebugModule(dom::Console* console,
                         script::GlobalEnvironment* global_environment,
                         RenderOverlay* render_overlay,
                         render_tree::ResourceProvider* resource_provider,
                         dom::Window* window, DebuggerState* debugger_state) {
  ConstructionData data(console, global_environment,
                        base::MessageLoop::current(), render_overlay,
                        resource_provider, window, debugger_state);
  Build(data);
}

DebugModule::DebugModule(dom::Console* console,
                         script::GlobalEnvironment* global_environment,
                         RenderOverlay* render_overlay,
                         render_tree::ResourceProvider* resource_provider,
                         dom::Window* window, DebuggerState* debugger_state,
                         base::MessageLoop* message_loop) {
  ConstructionData data(console, global_environment, message_loop,
                        render_overlay, resource_provider, window,
                        debugger_state);
  Build(data);
}

DebugModule::~DebugModule() {
  if (!is_frozen_) {
    // Shutting down without navigating. Give everything a chance to cleanup by
    // freezing, but throw away the state.
    Freeze();
  }
  if (debug_backend_) {
    debug_backend_->UnbindAgents();
  }
}

void DebugModule::Build(const ConstructionData& data) {
  DCHECK(data.message_loop);

  if (base::MessageLoop::current() == data.message_loop) {
    BuildInternal(data, NULL);
  } else {
    base::WaitableEvent created(
        base::WaitableEvent::ResetPolicy::MANUAL,
        base::WaitableEvent::InitialState::NOT_SIGNALED);
    data.message_loop->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&DebugModule::BuildInternal, base::Unretained(this), data,
                   base::Unretained(&created)));
    created.Wait();
  }

  DCHECK(debug_dispatcher_);
}

void DebugModule::BuildInternal(const ConstructionData& data,
                                base::WaitableEvent* created) {
  DCHECK(base::MessageLoop::current() == data.message_loop);
  DCHECK(data.console);
  DCHECK(data.global_environment);
  DCHECK(data.render_overlay);
  DCHECK(data.resource_provider);
  DCHECK(data.window);

  // Create the backend objects supporting the debugger agents.
  script_debugger_ =
      script::ScriptDebugger::CreateDebugger(data.global_environment, this);
  script_runner_.reset(
      new DebugScriptRunner(data.global_environment, script_debugger_.get(),
                            data.window->document()->csp_delegate()));
  debug_dispatcher_.reset(
      new DebugDispatcher(script_debugger_.get(), script_runner_.get()));
  debug_backend_ = WrapRefCounted(new DebugBackend(
      data.global_environment, script_debugger_.get(),
      base::Bind(&DebugModule::SendEvent, base::Unretained(this))));

  // Create render layers for the agents that need them and chain them
  // together. Ownership will be passed to the agent that uses each layer.
  // The layers will be painted in the reverse order they are listed here.
  std::unique_ptr<RenderLayer> page_render_layer(new RenderLayer(base::Bind(
      &RenderOverlay::SetOverlay, base::Unretained(data.render_overlay))));

  std::unique_ptr<RenderLayer> dom_render_layer(new RenderLayer(
      base::Bind(&RenderLayer::SetBackLayer, page_render_layer->AsWeakPtr())));

  // Create the agents that implement the various devtools protocol domains by
  // handling commands and sending event notifications. The script debugger
  // agent is an adapter to the engine-specific script debugger, which may
  // directly handle one or more protocol domains.
  script_debugger_agent_.reset(
      new ScriptDebuggerAgent(debug_dispatcher_.get(), script_debugger_.get()));
  console_agent_.reset(new ConsoleAgent(debug_dispatcher_.get(), data.console));
  log_agent_.reset(new LogAgent(debug_dispatcher_.get()));
  dom_agent_.reset(
      new DOMAgent(debug_dispatcher_.get(), std::move(dom_render_layer)));
  css_agent_ = WrapRefCounted(new CSSAgent(debug_dispatcher_.get()));
  page_agent_.reset(new PageAgent(debug_dispatcher_.get(), data.window,
                                  std::move(page_render_layer),
                                  data.resource_provider));
  tracing_agent_.reset(
      new TracingAgent(debug_dispatcher_.get(), script_debugger_.get()));

  // Hook up hybrid agent JavaScript to the DebugBackend.
  debug_backend_->BindAgents(css_agent_);

  // Restore the clients in the dispatcher first so they get events that the
  // agents might send as part of restoring state.
  if (data.debugger_state) {
    debug_dispatcher_->RestoreClients(
        std::move(data.debugger_state->attached_clients));
  }

  // Restore the agents with their state from before navigation. Do this
  // unconditionally to give the agents a place to initialize themselves whether
  // or not state is being restored.
  base::DictionaryValue* agents_state =
      data.debugger_state == nullptr ? nullptr
                                     : data.debugger_state->agents_state.get();
  script_debugger_agent_->Thaw(
      RemoveAgentState(kScriptDebuggerAgent, agents_state));
  console_agent_->Thaw(RemoveAgentState(kConsoleAgent, agents_state));
  log_agent_->Thaw(RemoveAgentState(kLogAgent, agents_state));
  dom_agent_->Thaw(RemoveAgentState(kDomAgent, agents_state));
  css_agent_->Thaw(RemoveAgentState(kCssAgent, agents_state));
  page_agent_->Thaw(RemoveAgentState(kPageAgent, agents_state));
  tracing_agent_->Thaw(RemoveAgentState(kTracingAgent, agents_state));

  is_frozen_ = false;

  if (created) {
    created->Signal();
  }
}

std::unique_ptr<DebuggerState> DebugModule::Freeze() {
  DCHECK(!is_frozen_);
  is_frozen_ = true;

  std::unique_ptr<DebuggerState> debugger_state(new DebuggerState());

  debugger_state->agents_state.reset(new base::DictionaryValue());
  base::DictionaryValue* agents_state = debugger_state->agents_state.get();
  StoreAgentState(agents_state, kScriptDebuggerAgent,
                  script_debugger_agent_->Freeze());
  StoreAgentState(agents_state, kConsoleAgent, console_agent_->Freeze());
  StoreAgentState(agents_state, kLogAgent, log_agent_->Freeze());
  StoreAgentState(agents_state, kDomAgent, dom_agent_->Freeze());
  StoreAgentState(agents_state, kCssAgent, css_agent_->Freeze());
  StoreAgentState(agents_state, kPageAgent, page_agent_->Freeze());
  StoreAgentState(agents_state, kTracingAgent, tracing_agent_->Freeze());

  // Take the clients from the dispatcher last so they still get events that the
  // agents might send as part of being frozen.
  debugger_state->attached_clients = debug_dispatcher_->ReleaseClients();

  return debugger_state;
}

void DebugModule::SendEvent(const std::string& method,
                            const base::Optional<std::string>& params) {
  DCHECK(debug_dispatcher_);
  debug_dispatcher_->SendEvent(method, params);
}

void DebugModule::OnScriptDebuggerPause() {
  DCHECK(debug_dispatcher_);
  debug_dispatcher_->SetPaused(true);
}

void DebugModule::OnScriptDebuggerResume() {
  DCHECK(debug_dispatcher_);
  debug_dispatcher_->SetPaused(false);
}

void DebugModule::OnScriptDebuggerResponse(const std::string& response) {
  DCHECK(script_debugger_agent_);
  script_debugger_agent_->SendCommandResponse(response);
}

void DebugModule::OnScriptDebuggerEvent(const std::string& event) {
  DCHECK(script_debugger_agent_);
  script_debugger_agent_->SendEvent(event);
}

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