// Copyright 2017 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 "core/dom/ClientRect.h"
#include "core/frame/LocalFrameView.h"
#include "core/frame/WebLocalFrameBase.h"
#include "core/input/EventHandler.h"
#include "core/layout/LayoutView.h"
#include "core/paint/PaintLayerScrollableArea.h"
#include "core/testing/sim/SimDisplayItemList.h"
#include "core/testing/sim/SimRequest.h"
#include "core/testing/sim/SimTest.h"
#include "platform/scroll/MainThreadScrollingReason.h"
#include "platform/scroll/ScrollerSizeMetrics.h"
#include "platform/testing/HistogramTester.h"
#include "platform/testing/TestingPlatformSupport.h"
#include "platform/testing/UnitTestHelpers.h"

#define EXPECT_WHEEL_BUCKET(reason, count)     \
  histogram_tester.ExpectBucketCount(          \
      "Renderer4.MainThreadWheelScrollReason", \
      GetBucketIndex(MainThreadScrollingReason::reason), count);

#define EXPECT_TOUCH_BUCKET(reason, count)       \
  histogram_tester.ExpectBucketCount(            \
      "Renderer4.MainThreadGestureScrollReason", \
      GetBucketIndex(MainThreadScrollingReason::reason), count);

#define EXPECT_WHEEL_TOTAL(count)                                            \
  histogram_tester.ExpectTotalCount("Renderer4.MainThreadWheelScrollReason", \
                                    count);

#define EXPECT_TOUCH_TOTAL(count)                                              \
  histogram_tester.ExpectTotalCount("Renderer4.MainThreadGestureScrollReason", \
                                    count);

namespace blink {

namespace {

class ScrollMetricsTest : public SimTest {
 public:
  void SetUpHtml(const char*);
  void Scroll(Element*, const WebGestureDevice);
};

class NonCompositedMainThreadScrollingReasonRecordTest
    : public ScrollMetricsTest {
 protected:
  int GetBucketIndex(uint32_t reason);
};

class ScrollBeginEventBuilder : public WebGestureEvent {
 public:
  ScrollBeginEventBuilder(IntPoint position,
                          FloatPoint delta,
                          WebGestureDevice device)
      : WebGestureEvent() {
    type_ = WebInputEvent::kGestureScrollBegin;
    x = global_x = position.X();
    y = global_y = position.Y();
    data.scroll_begin.delta_y_hint = delta.Y();
    source_device = device;
    frame_scale_ = 1;
  }
};

class ScrollUpdateEventBuilder : public WebGestureEvent {
 public:
  ScrollUpdateEventBuilder() : WebGestureEvent() {
    type_ = WebInputEvent::kGestureScrollUpdate;
    data.scroll_update.delta_x = 0.0f;
    data.scroll_update.delta_y = 1.0f;
    data.scroll_update.velocity_x = 0;
    data.scroll_update.velocity_y = 1;
    frame_scale_ = 1;
  }
};

class ScrollEndEventBuilder : public WebGestureEvent {
 public:
  ScrollEndEventBuilder() : WebGestureEvent() {
    type_ = WebInputEvent::kGestureScrollEnd;
    frame_scale_ = 1;
  }
};

int NonCompositedMainThreadScrollingReasonRecordTest::GetBucketIndex(
    uint32_t reason) {
  int index = 1;
  while (!(reason & 1)) {
    reason >>= 1;
    ++index;
  }
  DCHECK_EQ(reason, 1u);
  return index;
}

void ScrollMetricsTest::Scroll(Element* element,
                               const WebGestureDevice device) {
  DCHECK(element);
  DCHECK(element->getBoundingClientRect());
  ClientRect* rect = element->getBoundingClientRect();
  ScrollBeginEventBuilder scroll_begin(
      IntPoint(rect->left() + rect->width() / 2,
               rect->top() + rect->height() / 2),
      FloatPoint(0.f, 1.f), device);
  ScrollUpdateEventBuilder scroll_update;
  ScrollEndEventBuilder scroll_end;
  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_begin);
  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_update);
  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(scroll_end);
  ASSERT_GT(scroll_update.DeltaYInRootFrame(), 0);
}

void ScrollMetricsTest::SetUpHtml(const char* html_content) {
  WebView().Resize(WebSize(800, 600));
  SimRequest request("https://example.com/test.html", "text/html");
  LoadURL("https://example.com/test.html");
  request.Complete(html_content);
  Compositor().BeginFrame();
}

TEST_F(ScrollMetricsTest, ScrollerSizeOnPageLoadHistogramRecordingTest) {
  HistogramTester histogram_tester;
  SetUpHtml(
      "<!DOCTYPE html>"
      "<style>"
      " .smallBox { overflow: scroll; width: 100px; height: 100px; }"
      " .largeBox { overflow: auto; width: 500px; height: 500px; }"
      " .nonScrollableBox { overflow: auto; width: 200px; height: 200px; }"
      " .spacer { height: 1000px; }"
      " body { height: 2000px; width: 1000px; }"
      "</style>"
      "<div class='smallBox'><div class='spacer'></div></div>"
      "<div class='largeBox'><div class='spacer'></div></div>"
      "<div class='notScrollableBox'></div>"
      "<div style='width: 300px; height: 300px;'>"
      " <div class='spacer'></div>"
      "</div>");

  testing::RunPendingTasks();

  // SmallBox added to count.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnLoad", 10000,
                                     1);
  // LargeBox added to count.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnLoad",
                                     kScrollerSizeLargestBucket, 1);

  // Non-scrollable box is not added to count.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnLoad", 40000,
                                     0);

  // The fourth div without "overflow: scroll" is not supposed to be added to
  // count.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnLoad", 90000,
                                     0);
  // Root scroller is not added to count.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnLoad",
                                     kScrollerSizeLargestBucket, 1);
  histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnLoad", 2);
}

TEST_F(ScrollMetricsTest,
       ScrollerSizeOfMainThreadScrollingHistogramRecordingTest) {
  HistogramTester histogram_tester;
  SetUpHtml(
      "<!DOCTYPE html>"
      "<style>"
      " .container { width: 200px; height: 200px; overflow: scroll; }"
      " .box { width: 100px; height: 100px; overflow: scroll; }"
      " .spacer { height: 1000px; }"
      " .target { width: 200px; height: 200px; }"
      " body { height: 2000px; }"
      "</style>"
      "<div class='container'>"
      " <div id='box' class='box'>"
      "  <div id='content' class='spacer'></div>"
      " </div>"
      "</div>"
      "<div id='target' class='target'></div>");

  Element* box = GetDocument().getElementById("box");

  // Test wheel scroll on the box.
  Scroll(box, kWebGestureDeviceTouchpad);
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Wheel",
                                     10000, 1);
  // Only the first scrollable area is recorded.
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Wheel",
                                     40000, 0);
  histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Wheel",
                                    1);

  // Test touch scroll.
  Scroll(box, kWebGestureDeviceTouchscreen);
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Touch",
                                     10000, 1);
  histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch",
                                    1);

  // Scrolling the non-scrollable target leads to scroll the root layer which
  // doesn't add to count.
  Element* body_scroll_target = GetDocument().getElementById("target");
  Scroll(body_scroll_target, kWebGestureDeviceTouchscreen);
  histogram_tester.ExpectBucketCount("Event.Scroll.ScrollerSize.OnScroll_Touch",
                                     kScrollerSizeLargestBucket, 0);
  histogram_tester.ExpectTotalCount("Event.Scroll.ScrollerSize.OnScroll_Touch",
                                    1);
}

TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
       TouchAndWheelGeneralTest) {
  SetUpHtml(
      "<style>"
      " .box { overflow:scroll; width: 100px; height: 100px; }"
      " .translucent { opacity: 0.5; }"
      " .spacer { height: 1000px; }"
      "</style>"
      "<div id='box' class='translucent box'>"
      " <div class='spacer'></div>"
      "</div>");

  GetDocument().View()->UpdateAllLifecyclePhases();

  Element* box = GetDocument().getElementById("box");
  HistogramTester histogram_tester;

  // Test touch scroll.
  Scroll(box, kWebGestureDeviceTouchscreen);
  EXPECT_TOUCH_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);

  Scroll(box, kWebGestureDeviceTouchscreen);
  EXPECT_TOUCH_BUCKET(kHasOpacityAndLCDText, 2);
  EXPECT_TOUCH_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 2);
  EXPECT_TOUCH_TOTAL(4);

  // Test wheel scroll.
  Scroll(box, kWebGestureDeviceTouchpad);
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_TOTAL(2);
}

TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
       CompositedScrollableAreaTest) {
  SetUpHtml(
      "<style>"
      " .box { overflow:scroll; width: 100px; height: 100px; }"
      " .translucent { opacity: 0.5; }"
      " .composited { will-change: transform; }"
      " .spacer { height: 1000px; }"
      "</style>"
      "<div id='box' class='translucent box'>"
      " <div class='spacer'></div>"
      "</div>");

  WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
  GetDocument().View()->SetParentVisible(true);
  GetDocument().View()->SetSelfVisible(true);
  GetDocument().View()->UpdateAllLifecyclePhases();

  Element* box = GetDocument().getElementById("box");
  HistogramTester histogram_tester;

  Scroll(box, kWebGestureDeviceTouchpad);
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_TOTAL(2);

  box->setAttribute("class", "composited translucent box");
  GetDocument().View()->UpdateAllLifecyclePhases();
  Scroll(box, kWebGestureDeviceTouchpad);
  EXPECT_FALSE(ToLayoutBox(box->GetLayoutObject())
                   ->GetScrollableArea()
                   ->GetNonCompositedMainThreadScrollingReasons());
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_TOTAL(2);
}

TEST_F(NonCompositedMainThreadScrollingReasonRecordTest,
       NotScrollableAreaTest) {
  SetUpHtml(
      "<style>.box { overflow:scroll; width: 100px; height: 100px; }"
      " .translucent { opacity: 0.5; }"
      " .hidden { overflow: hidden; }"
      " .spacer { height: 1000px; }"
      "</style>"
      "<div id='box' class='translucent box'>"
      " <div class='spacer'></div>"
      "</div>");

  GetDocument().View()->UpdateAllLifecyclePhases();

  Element* box = GetDocument().getElementById("box");
  HistogramTester histogram_tester;

  Scroll(box, kWebGestureDeviceTouchpad);
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_TOTAL(2);

  box->setAttribute("class", "hidden translucent box");
  GetDocument().View()->UpdateAllLifecyclePhases();
  Scroll(box, kWebGestureDeviceTouchpad);
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_TOTAL(2);
}

TEST_F(NonCompositedMainThreadScrollingReasonRecordTest, NestedScrollersTest) {
  SetUpHtml(
      "<style>"
      " .container { overflow:scroll; width: 200px; height: 200px; }"
      " .box { overflow:scroll; width: 100px; height: 100px; }"
      " .translucent { opacity: 0.5; }"
      " .transform { transform: scale(0.8); }"
      " .with-border-radius { border: 5px solid; border-radius: 5px; }"
      " .spacer { height: 1000px; }"
      " .composited { will-change: transform; }"
      "</style>"
      "<div id='container' class='container with-border-radius'>"
      "  <div class='translucent box'>"
      "    <div id='inner' class='composited transform box'>"
      "      <div class='spacer'></div>"
      "    </div>"
      "    <div class='spacer'></div>"
      "  </div>"
      "  <div class='spacer'></div>"
      "</div>");

  WebView().GetSettings()->SetAcceleratedCompositingEnabled(true);
  GetDocument().View()->SetParentVisible(true);
  GetDocument().View()->SetSelfVisible(true);
  GetDocument().View()->UpdateAllLifecyclePhases();

  Element* box = GetDocument().getElementById("inner");
  HistogramTester histogram_tester;

  Scroll(box, kWebGestureDeviceTouchpad);
  // Scrolling the inner box will gather reasons from the scrolling chain. The
  // inner box itself has no reason because it's composited. Other scrollable
  // areas from the chain have corresponding reasons.
  EXPECT_WHEEL_BUCKET(kHasOpacityAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kBackgroundNotOpaqueInRectAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kIsNotStackingContextAndLCDText, 1);
  EXPECT_WHEEL_BUCKET(kHasBorderRadius, 1);
  EXPECT_WHEEL_BUCKET(kHasTransformAndLCDText, 0);
  EXPECT_WHEEL_TOTAL(4);
}

}  // namespace

}  // namespace blink
