// 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 TextHolder {
 public:
  FakeTextHolder(const std::string& text, const gfx::Rect& rect)
      : text_(text), rect_(rect) {}
  std::string text() const { return text_; }
  gfx::Rect rect() const { return rect_; }

 protected:
  ~FakeTextHolder() override = default;

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

class FakeCaptureContentLayerClient : public FakeContentLayerClient {
 public:
  void addTextHolder(scoped_refptr<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(), PaintFlags(),
          NodeHolder(holder));
      display_list->EndPaintOfUnpaired(holder->rect());
    }
    display_list->Finalize();
    return display_list;
  }

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

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

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

  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<scoped_refptr<FakeTextHolder>>* expected_result) {
    EXPECT_EQ(expected_result->size(), captured_content_.size());
    size_t expected_left_result = expected_result->size();
    for (auto c : captured_content_) {
      EXPECT_EQ(c.type, NodeHolder::Type::kTextHolder);
      for (auto it = expected_result->begin(); it != expected_result->end();
           ++it) {
        if (it->get() == c.text_holder.get()) {
          EXPECT_EQ(static_cast<FakeTextHolder*>(c.text_holder.get())->text(),
                    it->get()->text());
          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<NodeHolder> captured_content_;
  const gfx::Size device_bounds_;
  base::WeakPtrFactory<LayerTreeHostCaptureContentTest> weak_factory_;
};

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

  scoped_refptr<FakeTextHolder> text_holder_1_;
  scoped_refptr<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<scoped_refptr<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<scoped_refptr<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_ =
        base::MakeRefCounted<FakeTextHolder>("Text21", gfx::Rect(0, 0, 10, 5));
    client2_.addTextHolder(text_holder_21_);
    text_holder_22_ =
        base::MakeRefCounted<FakeTextHolder>("Text22", gfx::Rect(0, 5, 10, 5));
    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;
  scoped_refptr<FakeTextHolder> text_holder_21_;
  scoped_refptr<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<scoped_refptr<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<scoped_refptr<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<scoped_refptr<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<scoped_refptr<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
