// 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 "cobalt/debug/backend/dom_agent.h"

#include <string>

#include "base/bind.h"
#include "cobalt/math/matrix3_f.h"
#include "cobalt/math/transform_2d.h"
#include "cobalt/render_tree/brush.h"
#include "cobalt/render_tree/color_rgba.h"
#include "cobalt/render_tree/rect_node.h"

namespace cobalt {
namespace debug {
namespace backend {

namespace {
// Definitions from the set specified here:
// https://chromedevtools.github.io/devtools-protocol/tot/DOM
constexpr char kInspectorDomain[] = "DOM";

// File to load JavaScript DOM debugging domain implementation from.
constexpr char kScriptFile[] = "dom_agent.js";
}  // namespace

DOMAgent::DOMAgent(DebugDispatcher* dispatcher,
                   scoped_ptr<RenderLayer> render_layer)
    : dispatcher_(dispatcher),
      render_layer_(render_layer.Pass()),
      ALLOW_THIS_IN_INITIALIZER_LIST(commands_(this, kInspectorDomain)) {
  DCHECK(dispatcher_);

  commands_["disable"] = &DOMAgent::Disable;
  commands_["enable"] = &DOMAgent::Enable;
  commands_["highlightNode"] = &DOMAgent::HighlightNode;
  commands_["hideHighlight"] = &DOMAgent::HideHighlight;

  dispatcher_->AddDomain(kInspectorDomain, commands_.Bind());
}

DOMAgent::~DOMAgent() { dispatcher_->RemoveDomain(kInspectorDomain); }

void DOMAgent::Enable(const Command& command) {
  bool initialized = dispatcher_->RunScriptFile(kScriptFile);
  if (initialized) {
    command.SendResponse();
  } else {
    command.SendErrorResponse(Command::kInternalError,
                              "Cannot create DOM inspector.");
  }
}

void DOMAgent::Disable(const Command& command) { command.SendResponse(); }

// Unlike most other DOM command handlers, this one is not fully implemented
// in JavaScript. Instead, the JS object is used to look up the node from the
// parameters and return its bounding client rect, then the highlight itself
// is rendered by calling the C++ function |RenderHighlight| to set the render
// overlay.
void DOMAgent::HighlightNode(const Command& command) {
  // Get the bounding rectangle of the specified node.
  JSONObject json_dom_rect = dispatcher_->RunScriptCommand(
      "dom._getBoundingClientRect", command.GetParams());
  double x = 0.0;
  double y = 0.0;
  double width = 0.0;
  double height = 0.0;
  json_dom_rect->GetDouble("result.x", &x);
  json_dom_rect->GetDouble("result.y", &y);
  json_dom_rect->GetDouble("result.width", &width);
  json_dom_rect->GetDouble("result.height", &height);

  scoped_refptr<dom::DOMRect> dom_rect(
      new dom::DOMRect(static_cast<float>(x), static_cast<float>(y),
                       static_cast<float>(width), static_cast<float>(height)));

  // |highlight_config_value| still owned by |params|.
  JSONObject params = JSONParse(command.GetParams());
  base::DictionaryValue* highlight_config_value = NULL;
  bool got_highlight_config =
      params->GetDictionary("highlightConfig", &highlight_config_value);
  DCHECK(got_highlight_config);
  DCHECK(highlight_config_value);

  RenderHighlight(dom_rect, highlight_config_value);

  command.SendResponse();
}

void DOMAgent::HideHighlight(const Command& command) {
  render_layer_->SetFrontLayer(scoped_refptr<render_tree::Node>());
  command.SendResponse();
}

void DOMAgent::RenderHighlight(
    const scoped_refptr<dom::DOMRect>& bounding_rect,
    const base::DictionaryValue* highlight_config_value) {
  // TODO: Should also render borders, etc.

  // Content color is optional in the parameters, so use a fallback.
  int r = 112;
  int g = 168;
  int b = 219;
  double a = 0.66;
  const base::DictionaryValue* content_color = NULL;
  bool got_content_color =
      highlight_config_value->GetDictionary("contentColor", &content_color);
  if (got_content_color && content_color) {
    content_color->GetInteger("r", &r);
    content_color->GetInteger("g", &g);
    content_color->GetInteger("b", &b);
    content_color->GetDouble("a", &a);
  }
  render_tree::ColorRGBA color(r / 255.0f, g / 255.0f, b / 255.0f,
                               static_cast<float>(a));

  scoped_ptr<render_tree::Brush> background_brush(
      new render_tree::SolidColorBrush(color));
  scoped_refptr<render_tree::Node> rect = new render_tree::RectNode(
      math::RectF(bounding_rect->x(), bounding_rect->y(),
                  bounding_rect->width(), bounding_rect->height()),
      background_brush.Pass());
  render_layer_->SetFrontLayer(rect);
}

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