// Copyright 2015 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 "third_party/blink/renderer/core/scroll/scrollable_area.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_test_suite.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mock.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme_overlay_mock.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h"
#include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"

namespace blink {

namespace {

using testing::_;
using testing::Return;

class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeMock {
 public:
  MOCK_CONST_METHOD0(ShouldRepaintAllPartsOnInvalidation, bool());
  MOCK_CONST_METHOD3(InvalidateOnThumbPositionChange,
                     ScrollbarPart(const Scrollbar&, float, float));
};

}  // namespace

class ScrollableAreaTest : public testing::Test {};

TEST_F(ScrollableAreaTest, ScrollAnimatorCurrentPositionShouldBeSync) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(0, 100));
  scrollable_area->SetScrollOffset(ScrollOffset(0, 10000), kCompositorScroll);
  EXPECT_EQ(100.0,
            scrollable_area->GetScrollAnimator().CurrentOffset().Height());
}

TEST_F(ScrollableAreaTest, ScrollbarTrackAndThumbRepaint) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  ScrollbarThemeWithMockInvalidation theme;
  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(0, 100));
  Scrollbar* scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);

  EXPECT_CALL(theme, ShouldRepaintAllPartsOnInvalidation())
      .WillRepeatedly(Return(true));
  EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());
  scrollbar->SetNeedsPaintInvalidation(kNoPart);
  EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());

  scrollbar->ClearTrackNeedsRepaint();
  scrollbar->ClearThumbNeedsRepaint();
  EXPECT_FALSE(scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(scrollbar->ThumbNeedsRepaint());
  scrollbar->SetNeedsPaintInvalidation(kThumbPart);
  EXPECT_TRUE(scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());

  // When not all parts are repainted on invalidation,
  // setNeedsPaintInvalidation sets repaint bits only on the requested parts.
  EXPECT_CALL(theme, ShouldRepaintAllPartsOnInvalidation())
      .WillRepeatedly(Return(false));
  scrollbar->ClearTrackNeedsRepaint();
  scrollbar->ClearThumbNeedsRepaint();
  EXPECT_FALSE(scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(scrollbar->ThumbNeedsRepaint());
  scrollbar->SetNeedsPaintInvalidation(kThumbPart);
  EXPECT_FALSE(scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(scrollbar->ThumbNeedsRepaint());

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST_F(ScrollableAreaTest, ScrollbarGraphicsLayerInvalidation) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  ScrollbarTheme::SetMockScrollbarsEnabled(true);
  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(0, 100));
  FakeGraphicsLayerClient graphics_layer_client;
  graphics_layer_client.SetIsTrackingRasterInvalidations(true);
  FakeGraphicsLayer graphics_layer(graphics_layer_client);
  graphics_layer.SetDrawsContent(true);
  graphics_layer.SetSize(gfx::Size(111, 222));

  EXPECT_CALL(*scrollable_area, LayerForHorizontalScrollbar())
      .WillRepeatedly(Return(&graphics_layer));

  Scrollbar* scrollbar = Scrollbar::Create(
      scrollable_area, kHorizontalScrollbar, kRegularScrollbar, nullptr);
  graphics_layer.ResetTrackedRasterInvalidations();
  scrollbar->SetNeedsPaintInvalidation(kNoPart);
  EXPECT_TRUE(graphics_layer.HasTrackedRasterInvalidations());

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST_F(ScrollableAreaTest, InvalidatesNonCompositedScrollbarsWhenThumbMoves) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  ScrollbarThemeWithMockInvalidation theme;
  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(100, 100));
  Scrollbar* horizontal_scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);
  Scrollbar* vertical_scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kVerticalScrollbar, kRegularScrollbar, &theme);
  EXPECT_CALL(*scrollable_area, HorizontalScrollbar())
      .WillRepeatedly(Return(horizontal_scrollbar));
  EXPECT_CALL(*scrollable_area, VerticalScrollbar())
      .WillRepeatedly(Return(vertical_scrollbar));

  // Regardless of whether the theme invalidates any parts, non-composited
  // scrollbars have to be repainted if the thumb moves.
  EXPECT_CALL(*scrollable_area, LayerForHorizontalScrollbar())
      .WillRepeatedly(Return(nullptr));
  EXPECT_CALL(*scrollable_area, LayerForVerticalScrollbar())
      .WillRepeatedly(Return(nullptr));
  ASSERT_FALSE(scrollable_area->HasLayerForVerticalScrollbar());
  ASSERT_FALSE(scrollable_area->HasLayerForHorizontalScrollbar());
  EXPECT_CALL(theme, ShouldRepaintAllPartsOnInvalidation())
      .WillRepeatedly(Return(false));
  EXPECT_CALL(theme, InvalidateOnThumbPositionChange(_, _, _))
      .WillRepeatedly(Return(kNoPart));

  // A scroll in each direction should only invalidate one scrollbar.
  scrollable_area->SetScrollOffset(ScrollOffset(0, 50), kProgrammaticScroll);
  EXPECT_FALSE(scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());
  EXPECT_TRUE(scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
  scrollable_area->ClearNeedsPaintInvalidationForScrollControls();
  scrollable_area->SetScrollOffset(ScrollOffset(50, 50), kProgrammaticScroll);
  EXPECT_TRUE(scrollable_area->HorizontalScrollbarNeedsPaintInvalidation());
  EXPECT_FALSE(scrollable_area->VerticalScrollbarNeedsPaintInvalidation());
  scrollable_area->ClearNeedsPaintInvalidationForScrollControls();

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  ScrollbarThemeWithMockInvalidation theme;
  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(100, 100));
  Scrollbar* horizontal_scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);
  horizontal_scrollbar->ClearTrackNeedsRepaint();
  horizontal_scrollbar->ClearThumbNeedsRepaint();
  Scrollbar* vertical_scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kVerticalScrollbar, kRegularScrollbar, &theme);
  vertical_scrollbar->ClearTrackNeedsRepaint();
  vertical_scrollbar->ClearThumbNeedsRepaint();
  EXPECT_CALL(*scrollable_area, HorizontalScrollbar())
      .WillRepeatedly(Return(horizontal_scrollbar));
  EXPECT_CALL(*scrollable_area, VerticalScrollbar())
      .WillRepeatedly(Return(vertical_scrollbar));

  // Composited scrollbars only need repainting when parts become invalid
  // (e.g. if the track changes appearance when the thumb reaches the end).
  FakeGraphicsLayerClient graphics_layer_client;
  graphics_layer_client.SetIsTrackingRasterInvalidations(true);
  FakeGraphicsLayer layer_for_horizontal_scrollbar(graphics_layer_client);
  layer_for_horizontal_scrollbar.SetDrawsContent(true);
  layer_for_horizontal_scrollbar.SetSize(gfx::Size(10, 10));
  FakeGraphicsLayer layer_for_vertical_scrollbar(graphics_layer_client);
  layer_for_vertical_scrollbar.SetDrawsContent(true);
  layer_for_vertical_scrollbar.SetSize(gfx::Size(10, 10));
  EXPECT_CALL(*scrollable_area, LayerForHorizontalScrollbar())
      .WillRepeatedly(Return(&layer_for_horizontal_scrollbar));
  EXPECT_CALL(*scrollable_area, LayerForVerticalScrollbar())
      .WillRepeatedly(Return(&layer_for_vertical_scrollbar));
  ASSERT_TRUE(scrollable_area->HasLayerForHorizontalScrollbar());
  ASSERT_TRUE(scrollable_area->HasLayerForVerticalScrollbar());
  EXPECT_CALL(theme, ShouldRepaintAllPartsOnInvalidation())
      .WillRepeatedly(Return(false));

  // First, we'll scroll horizontally, and the theme will require repainting
  // the back button (i.e. the track).
  EXPECT_CALL(theme, InvalidateOnThumbPositionChange(_, _, _))
      .WillOnce(Return(kBackButtonStartPart));
  scrollable_area->SetScrollOffset(ScrollOffset(50, 0), kProgrammaticScroll);
  EXPECT_TRUE(layer_for_horizontal_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_FALSE(layer_for_vertical_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_TRUE(horizontal_scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(horizontal_scrollbar->ThumbNeedsRepaint());
  layer_for_horizontal_scrollbar.ResetTrackedRasterInvalidations();
  horizontal_scrollbar->ClearTrackNeedsRepaint();

  // Next, we'll scroll vertically, but invalidate the thumb.
  EXPECT_CALL(theme, InvalidateOnThumbPositionChange(_, _, _))
      .WillOnce(Return(kThumbPart));
  scrollable_area->SetScrollOffset(ScrollOffset(50, 50), kProgrammaticScroll);
  EXPECT_FALSE(layer_for_horizontal_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_TRUE(layer_for_vertical_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
  EXPECT_TRUE(vertical_scrollbar->ThumbNeedsRepaint());
  layer_for_vertical_scrollbar.ResetTrackedRasterInvalidations();
  vertical_scrollbar->ClearThumbNeedsRepaint();

  // Next we'll scroll in both, but the thumb position moving requires no
  // invalidations. Nonetheless the GraphicsLayer should be invalidated,
  // because we still need to update the underlying layer (though no
  // rasterization will be required).
  EXPECT_CALL(theme, InvalidateOnThumbPositionChange(_, _, _))
      .Times(2)
      .WillRepeatedly(Return(kNoPart));
  scrollable_area->SetScrollOffset(ScrollOffset(70, 70), kProgrammaticScroll);
  EXPECT_TRUE(layer_for_horizontal_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_TRUE(layer_for_vertical_scrollbar.HasTrackedRasterInvalidations());
  EXPECT_FALSE(horizontal_scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(horizontal_scrollbar->ThumbNeedsRepaint());
  EXPECT_FALSE(vertical_scrollbar->TrackNeedsRepaint());
  EXPECT_FALSE(vertical_scrollbar->ThumbNeedsRepaint());

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

TEST_F(ScrollableAreaTest, RecalculatesScrollbarOverlayIfBackgroundChanges) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(0, 100));

  EXPECT_EQ(kScrollbarOverlayColorThemeDark,
            scrollable_area->GetScrollbarOverlayColorTheme());
  scrollable_area->RecalculateScrollbarOverlayColorTheme(Color(34, 85, 51));
  EXPECT_EQ(kScrollbarOverlayColorThemeLight,
            scrollable_area->GetScrollbarOverlayColorTheme());
  scrollable_area->RecalculateScrollbarOverlayColorTheme(Color(236, 143, 185));
  EXPECT_EQ(kScrollbarOverlayColorThemeDark,
            scrollable_area->GetScrollbarOverlayColorTheme());
}

TEST_F(ScrollableAreaTest, ScrollableAreaDidScroll) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(100, 100));
  scrollable_area->DidScroll(FloatPoint(40, 51));

  EXPECT_EQ(40, scrollable_area->ScrollOffsetInt().Width());
  EXPECT_EQ(51, scrollable_area->ScrollOffsetInt().Height());
}

// Scrollbars in popups shouldn't fade out since they aren't composited and thus
// they don't appear on hover so users without a wheel can't scroll if they fade
// out.
TEST_F(ScrollableAreaTest, PopupOverlayScrollbarShouldNotFadeOut) {
  ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
      platform;

  ScopedOverlayScrollbarsForTest overlay_scrollbars(true);
  ScrollbarTheme::SetMockScrollbarsEnabled(true);

  MockScrollableArea* scrollable_area =
      MockScrollableArea::Create(ScrollOffset(0, 100));
  scrollable_area->SetIsPopup();

  ScrollbarThemeOverlayMock& theme =
      (ScrollbarThemeOverlayMock&)scrollable_area->GetPageScrollbarTheme();
  theme.SetOverlayScrollbarFadeOutDelay(TimeDelta::FromSeconds(1));
  Scrollbar* scrollbar = Scrollbar::CreateForTesting(
      scrollable_area, kHorizontalScrollbar, kRegularScrollbar, &theme);

  DCHECK(scrollbar->IsOverlayScrollbar());
  DCHECK(scrollbar->Enabled());

  scrollable_area->ShowOverlayScrollbars();

  // No fade out animation should be posted.
  EXPECT_FALSE(scrollable_area->fade_overlay_scrollbars_timer_);

  // Forced GC in order to finalize objects depending on the mock object.
  ThreadState::Current()->CollectAllGarbage();
}

}  // namespace blink
