// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/trees/layer_tree_host.h"

#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/transform_node.h"

namespace cc {
namespace {

class FakeTextHolder {
 public:
  FakeTextHolder(const std::string& text, const gfx::Rect& rect, NodeId node_id)
      : text_(text), rect_(rect), node_id_(node_id) {}
  std::string text() const { return text_; }
  gfx::Rect rect() const { return rect_; }
  NodeId node_id() const { return node_id_; }

 private:
  std::string text_;
  gfx::Rect rect_;
  NodeId node_id_;
};

class FakeCaptureContentLayerClient : public FakeContentLayerClient {
 public:
  void addTextHolder(const FakeTextHolder& holder) {
    holders_.push_back(holder);
  }

  scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
      PaintingControlSetting painting_control) override {
    auto display_list = base::MakeRefCounted<DisplayItemList>();
    for (auto& holder : holders_) {
      display_list->StartPaint();
      display_list->push<DrawTextBlobOp>(
          SkTextBlob::MakeFromString(holder.text().data(), SkFont()),
          holder.rect().x(), holder.rect().y(), holder.node_id(), PaintFlags());
      display_list->EndPaintOfUnpaired(holder.rect());
    }
    display_list->Finalize();
    return display_list;
  }

 private:
  std::vector<const FakeTextHolder> holders_;
};

// These tests are for LayerTreeHost::CaptureContent().
class LayerTreeHostCaptureContentTest : public LayerTreeTest {
 public:
  ~LayerTreeHostCaptureContentTest() override = default;

 protected:
  LayerTreeHostCaptureContentTest() : device_bounds_(10, 10) {}

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DidCommit() override { PostCaptureContentToMainThread(); }

  void SetupRootPictureLayer(const gfx::Size& size) {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(size);

    client_.set_bounds(size);
    root_picture_layer_ = FakePictureLayer::Create(&client_);
    root_picture_layer_->SetBounds(size);
    root->AddChild(root_picture_layer_);

    layer_tree_host()->SetRootLayer(root);
    layer_tree_host()->SetViewportVisibleRect(gfx::Rect(device_bounds_));
  }

  void VerifyCapturedContent(std::vector<FakeTextHolder>* expected_result) {
    EXPECT_EQ(expected_result->size(), captured_content_.size());
    size_t expected_left_result = expected_result->size();
    for (auto& c : captured_content_) {
      for (auto it = expected_result->begin(); it != expected_result->end();
           ++it) {
        if (it->node_id() == c) {
          expected_result->erase(it);
          break;
        }
      }
      EXPECT_EQ(--expected_left_result, expected_result->size());
    }
  }

  FakeCaptureContentLayerClient client_;

 private:
  void PostCaptureContentToMainThread() {
    MainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(&LayerTreeHostCaptureContentTest::CaptureContent,
                       weak_factory_.GetWeakPtr()));
  }

  void CaptureContent() {
    captured_content_.clear();
    layer_tree_host()->CaptureContent(&captured_content_);
    EndTest();
  }

  scoped_refptr<FakePictureLayer> root_picture_layer_;
  std::vector<NodeId> captured_content_;
  const gfx::Size device_bounds_;
  base::WeakPtrFactory<LayerTreeHostCaptureContentTest> weak_factory_{this};
};

class LayerTreeHostCaptureContentTestBasic
    : public LayerTreeHostCaptureContentTest {
 protected:
  void SetupTextHolders(const gfx::Rect& rect1, const gfx::Rect& rect2) {
    text_holder_1_ = std::make_unique<FakeTextHolder>("Text1", rect1, 1);
    client_.addTextHolder(*text_holder_1_);
    text_holder_2_ = std::make_unique<FakeTextHolder>("Text2", rect2, 2);
    client_.addTextHolder(*text_holder_2_);
  }

  std::unique_ptr<FakeTextHolder> text_holder_1_;
  std::unique_ptr<FakeTextHolder> text_holder_2_;
};

// Test that one DrawTextBlobOp is on-screen, another isn't.
class LayerTreeHostCaptureContentTestOneVisible
    : public LayerTreeHostCaptureContentTestBasic {
 protected:
  void SetupTree() override {
    // One is visible.
    SetupTextHolders(gfx::Rect(0, 0, 5, 5), gfx::Rect(11, 0, 5, 5));
    SetupRootPictureLayer(gfx::Size(10, 10));
  }

  void AfterTest() override {
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCaptureContentTestOneVisible);

// Test that both DrawTextBlobOps are on-screen.
class LayerTreeHostCaptureContentTestTwoVisible
    : public LayerTreeHostCaptureContentTestBasic {
 protected:
  void SetupTree() override {
    // One is visible, another is partial visible.
    SetupTextHolders(gfx::Rect(0, 0, 5, 5), gfx::Rect(9, 0, 5, 5));
    SetupRootPictureLayer(gfx::Size(10, 10));
  }

  void AfterTest() override {
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    expected_result.push_back(*text_holder_2_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCaptureContentTestTwoVisible);

// Base class for two layers tests.
class LayerTreeHostCaptureContentTestTwoLayers
    : public LayerTreeHostCaptureContentTestBasic {
 protected:
  void SetupTree() override {
    SetupTextHolders(gfx::Rect(0, 0, 5, 5), gfx::Rect(5, 5, 5, 5));
    SetupRootPictureLayer(gfx::Size(10, 10));
    SetupSecondaryPictureLayer(gfx::Size(10, 10));
  }

  void DidCommit() override {
    LayerTreeHostCaptureContentTestBasic::DidCommit();
    OnSetupSecondaryLayTransform();
  }

  virtual void OnSetupSecondaryLayTransform() {}

  virtual bool IsSecondaryPictureLayerContentsOpaque() { return true; }

  // Setup transform node for secondary picture layer, must be called in
  // OnSetupSecondaryLayTransform().
  void SetupTransform(const gfx::Vector2dF& translate) {
    TransformNode transform_node;
    transform_node.source_node_id = 0;
    transform_node.local.Translate(translate);
    transform_node.id =
        layer_tree_host()->property_trees()->transform_tree.Insert(
            transform_node, 0);
    picture_layer->SetTransformTreeIndex(transform_node.id);
    layer_tree_host()->property_trees()->transform_tree.UpdateTransforms(
        transform_node.id);
  }

  void SetupSecondaryPictureLayer(const gfx::Size& size) {
    // Add text to layer.
    text_holder_21_ =
        std::make_unique<FakeTextHolder>("Text21", gfx::Rect(0, 0, 10, 5), 21);
    client2_.addTextHolder(*text_holder_21_);
    text_holder_22_ =
        std::make_unique<FakeTextHolder>("Text22", gfx::Rect(0, 5, 10, 5), 22);
    client2_.addTextHolder(*text_holder_22_);
    client2_.set_bounds(size);

    // Create layer.
    picture_layer = FakePictureLayer::Create(&client2_);
    picture_layer->SetBounds(size);
    picture_layer->SetContentsOpaque(IsSecondaryPictureLayerContentsOpaque());
    layer_tree_host()->root_layer()->AddChild(picture_layer);
  }

  scoped_refptr<FakePictureLayer> picture_layer;
  std::unique_ptr<FakeTextHolder> text_holder_21_;
  std::unique_ptr<FakeTextHolder> text_holder_22_;
  FakeCaptureContentLayerClient client2_;
};

// Test that one layer is within screen, another isn't.
class LayerTreeHostCaptureContentTestOneLayerVisible
    : public LayerTreeHostCaptureContentTestTwoLayers {
  void OnSetupSecondaryLayTransform() override {
    // Moves the layer out of visual port.
    SetupTransform(gfx::Vector2dF(0, 10));
  }

  void AfterTest() override {
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    expected_result.push_back(*text_holder_2_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCaptureContentTestOneLayerVisible);

// Test that the upper layer is partially on-screen, the under layer fully
// occupies the screen, all layer's on-screen content are returned even the
// upper layer is opaque.
class LayerTreeHostCaptureContentTestTwoLayersVisible
    : public LayerTreeHostCaptureContentTestTwoLayers {
  void OnSetupSecondaryLayTransform() override {
    SetupTransform(gfx::Vector2dF(0, 8));
  }

  void AfterTest() override {
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    expected_result.push_back(*text_holder_2_);
    expected_result.push_back(*text_holder_21_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostCaptureContentTestTwoLayersVisible);

// Test that the upper layer is transparent, the under layer fully occupies the
// screen, all layer's on-screen content are returned.
class LayerTreeHostCaptureContentTestTwoLayersVisibleAndTransparent
    : public LayerTreeHostCaptureContentTestTwoLayersVisible {
  bool IsSecondaryPictureLayerContentsOpaque() override { return false; }

  void AfterTest() override {
    // All 3  TextHolders are returned.
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    expected_result.push_back(*text_holder_2_);
    expected_result.push_back(*text_holder_21_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostCaptureContentTestTwoLayersVisibleAndTransparent);

// Test that the upper layer is partially visible, but doesn't overlay screen in
// either direction, the under layer's content will be captured even it is fully
// overlaid by the upper layer.
class LayerTreeHostCaptureContentTestUpperLayerPartialOverlay
    : public LayerTreeHostCaptureContentTestTwoLayers {
  void OnSetupSecondaryLayTransform() override {
    SetupTransform(gfx::Vector2dF(2, 2));
  }

  void AfterTest() override {
    std::vector<FakeTextHolder> expected_result;
    expected_result.push_back(*text_holder_1_);
    expected_result.push_back(*text_holder_2_);
    expected_result.push_back(*text_holder_21_);
    expected_result.push_back(*text_holder_22_);
    VerifyCapturedContent(&expected_result);
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostCaptureContentTestUpperLayerPartialOverlay);

}  // namespace
}  // namespace cc
