// 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/lottie_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(LottieNode* lottie) 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(LottieNode* lottie) {
  AddNamedNodeString(lottie, "LottieNode");
  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 {
    brush_type_ = "(SolidColorBrush)";
  }
  void Visit(const cobalt::render_tree::LinearGradientBrush*
                 linear_gradient_brush) override {
    brush_type_ = "(LinearGradientBrush)";
  }
  void Visit(const cobalt::render_tree::RadialGradientBrush*
                 radial_gradient_brush) override {
    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
