// 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/render_tree/dump_render_tree_to_string.h"

#include <sstream>

#include "cobalt/render_tree/clear_rect_node.h"
#include "cobalt/render_tree/composition_node.h"
#include "cobalt/render_tree/filter_node.h"
#include "cobalt/render_tree/image_node.h"
#include "cobalt/render_tree/matrix_transform_3d_node.h"
#include "cobalt/render_tree/matrix_transform_node.h"
#include "cobalt/render_tree/node_visitor.h"
#include "cobalt/render_tree/punch_through_video_node.h"
#include "cobalt/render_tree/rect_node.h"
#include "cobalt/render_tree/rect_shadow_node.h"
#include "cobalt/render_tree/text_node.h"

namespace cobalt {
namespace render_tree {

namespace animations {
class AnimateNode;
}  // namespace animations

namespace {

// A render tree visitor that accumulates node dumps to text within a
// std::ostringstream object.
class DebugTreePrinter : public NodeVisitor {
 public:
  DebugTreePrinter() : indent_(0) {}

  void Visit(animations::AnimateNode* /* animate */) override { NOTREACHED(); }
  void Visit(ClearRectNode* clear_rect) override;
  void Visit(CompositionNode* composition) override;
  void Visit(FilterNode* text) override;
  void Visit(ImageNode* image) override;
  void Visit(MatrixTransform3DNode* transform) override;
  void Visit(MatrixTransformNode* transform) override;
  void Visit(PunchThroughVideoNode* punch_through) override;
  void Visit(RectNode* rect) override;
  void Visit(RectShadowNode* rect) override;
  void Visit(TextNode* text) override;

  // Returns the final result after visitation is complete.
  const std::string Result() const { return result_.str(); }

 private:
  // Adds an appropriate number of indent characters according to |indent_|.
  void AddIndentString();

  // Adds general render tree node information (e.g. bounds) for a given node.
  void AddNodeInfoString(Node* node);

  // A simple function that most of the time dumps all the generic information
  // about a given node.
  void AddNamedNodeString(Node* node, const char* type);

  // Helper function to increment and decrement |indent_|.
  class ScopedIncrement {
   public:
    explicit ScopedIncrement(int* value) : value_(value) { ++(*value_); }
    ~ScopedIncrement() { --(*value_); }

   private:
    int* value_;
  };

  // The results object in which we accumulate our string representation.
  std::ostringstream result_;

  // Our current indent when printing lines of information.
  int indent_;
};

void DebugTreePrinter::Visit(ClearRectNode* clear_rect) {
  AddNamedNodeString(clear_rect, "ClearRectNode");
  result_ << "\n";
}

void DebugTreePrinter::Visit(CompositionNode* composition) {
  AddNamedNodeString(composition, "CompositionNode");
  result_ << "\n";

  ScopedIncrement scoped_increment(&indent_);

  const render_tree::CompositionNode::Children& children =
      composition->data().children();
  for (render_tree::CompositionNode::Children::const_iterator iter =
           children.begin();
       iter != children.end(); ++iter) {
    (*iter)->Accept(this);
  }
}

void DebugTreePrinter::Visit(FilterNode* filter) {
  AddNamedNodeString(filter, "FilterNode");

  // Add some additional information to the FilterNode output to indicate which
  // filters were in effect.
  result_ << " { Filters: (";

  if (filter->data().opacity_filter) {
    result_ << "opacity, ";
  }
  if (filter->data().viewport_filter) {
    result_ << "viewport, ";
  }
  if (filter->data().blur_filter) {
    result_ << "blur_filter, ";
  }
  result_ << ") }\n";

  ScopedIncrement scoped_increment(&indent_);

  filter->data().source->Accept(this);
}

void DebugTreePrinter::Visit(ImageNode* image) {
  AddNamedNodeString(image, "ImageNode");
  result_ << "\n";
}

void DebugTreePrinter::Visit(MatrixTransform3DNode* transform) {
  AddNamedNodeString(transform, "MatrixTransform3DNode");
  result_ << "\n";

  ScopedIncrement scoped_increment(&indent_);

  transform->data().source->Accept(this);
}

void DebugTreePrinter::Visit(MatrixTransformNode* transform) {
  AddNamedNodeString(transform, "MatrixTransformNode");
  result_ << "\n";

  ScopedIncrement scoped_increment(&indent_);

  transform->data().source->Accept(this);
}

void DebugTreePrinter::Visit(PunchThroughVideoNode* punch_through) {
  AddNamedNodeString(punch_through, "PunchThroughVideoNode");
  result_ << "\n";
}

namespace {
class BrushPrinterVisitor : public render_tree::BrushVisitor {
 public:
  BrushPrinterVisitor() {}

  void Visit(
      const cobalt::render_tree::SolidColorBrush* solid_color_brush) override {
    SB_UNREFERENCED_PARAMETER(solid_color_brush);
    brush_type_ = "(SolidColorBrush)";
  }
  void Visit(const cobalt::render_tree::LinearGradientBrush*
                 linear_gradient_brush) override {
    SB_UNREFERENCED_PARAMETER(linear_gradient_brush);
    brush_type_ = "(LinearGradientBrush)";
  }
  void Visit(const cobalt::render_tree::RadialGradientBrush*
                 radial_gradient_brush) override {
    SB_UNREFERENCED_PARAMETER(radial_gradient_brush);
    brush_type_ = "(RadialGradientBrush)";
  }

  const std::string& brush_type() const { return brush_type_; }

 private:
  std::string brush_type_;
};
}  // namespace

void DebugTreePrinter::Visit(RectNode* rect) {
  AddNamedNodeString(rect, "RectNode ");
  if (rect->data().background_brush) {
    BrushPrinterVisitor printer_brush_visitor;
    rect->data().background_brush->Accept(&printer_brush_visitor);
    result_ << printer_brush_visitor.brush_type();
  }
  result_ << "\n";
}

void DebugTreePrinter::Visit(RectShadowNode* rect) {
  AddNamedNodeString(rect, "RectShadowNode");
  result_ << "\n";
}

void DebugTreePrinter::Visit(TextNode* text) {
  AddNamedNodeString(text, "TextNode");
  result_ << "\n";
}

void DebugTreePrinter::AddIndentString() {
  result_ << std::string(static_cast<size_t>(indent_) * 2, ' ');
}

void DebugTreePrinter::AddNodeInfoString(Node* node) {
  const math::RectF bounds = node->GetBounds();

  result_ << "{ Bounds: (" << bounds.x() << ", " << bounds.y() << ", "
          << bounds.width() << ", " << bounds.height() << ") }";
}

void DebugTreePrinter::AddNamedNodeString(Node* node, const char* type_name) {
  AddIndentString();
  result_ << type_name << " ";
  AddNodeInfoString(node);
}

}  // namespace

std::string DumpRenderTreeToString(render_tree::Node* node) {
  DebugTreePrinter tree_printer;
  node->Accept(&tree_printer);

  return tree_printer.Result();
}

}  // namespace render_tree
}  // namespace cobalt
