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

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  Widget buildTest(
    GlobalKey box1Key,
    GlobalKey box2Key,
    GlobalKey box3Key,
    ScrollController controller, {
    Axis axis = Axis.vertical,
    bool reverse = false,
  }) {
    final AxisDirection axisDirection;
    switch (axis) {
      case Axis.horizontal:
        axisDirection = reverse ? AxisDirection.left : AxisDirection.right;
        break;
      case Axis.vertical:
        axisDirection = reverse ? AxisDirection.up : AxisDirection.down;
        break;
    }

    return Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(size: Size(800.0, 600.0)),
        child: ScrollConfiguration(
          behavior: const ScrollBehavior().copyWith(overscroll: false),
          child: StretchingOverscrollIndicator(
            axisDirection: axisDirection,
            child: CustomScrollView(
              reverse: reverse,
              scrollDirection: axis,
              controller: controller,
              slivers: <Widget>[
                SliverToBoxAdapter(child: Container(
                  color: const Color(0xD0FF0000),
                  key: box1Key,
                  height: 250.0,
                  width: 300.0,
                )),
                SliverToBoxAdapter(child: Container(
                  color: const Color(0xFFFFFF00),
                  key: box2Key,
                  height: 250.0,
                  width: 300.0,
                )),
                SliverToBoxAdapter(child: Container(
                  color: const Color(0xFF6200EA),
                  key: box3Key,
                  height: 250.0,
                  width: 300.0,
                )),
              ],
            ),
          ),
        ),
      ),
    );
  }

  testWidgets('Stretch overscroll vertically', (WidgetTester tester) async {
    final GlobalKey box1Key = GlobalKey();
    final GlobalKey box2Key = GlobalKey();
    final GlobalKey box3Key = GlobalKey();
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      buildTest(box1Key, box2Key, box3Key, controller),
    );

    expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
    expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
    final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
    final RenderBox box3 = tester.renderObject(find.byKey(box3Key));

    expect(controller.offset, 0.0);
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 250.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(0.0, 500.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.vertical.start.png'),
    );

    TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll the start
    await gesture.moveBy(const Offset(0.0, 200.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero).dy, greaterThan(255.0));
    expect(box3.localToGlobal(Offset.zero).dy, greaterThan(510.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.vertical.start.stretched.png'),
    );

    await gesture.up();
    await tester.pumpAndSettle();

    // Stretch released back to the start
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 250.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(0.0, 500.0));

    // Jump to end of the list
    controller.jumpTo(controller.position.maxScrollExtent);
    await tester.pumpAndSettle();
    expect(controller.offset, 150.0);
    expect(box1.localToGlobal(Offset.zero).dy, -150.0);
    expect(box2.localToGlobal(Offset.zero).dy, 100.0);
    expect(box3.localToGlobal(Offset.zero).dy, 350.0);
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.vertical.end.png'),
    );

    gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll the end
    await gesture.moveBy(const Offset(0.0, -200.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero).dy, lessThan(-165));
    expect(box2.localToGlobal(Offset.zero).dy, lessThan(90.0));
    expect(box3.localToGlobal(Offset.zero).dy, lessThan(350.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.vertical.end.stretched.png'),
    );

    await gesture.up();
    await tester.pumpAndSettle();

    // Stretch released back
    expect(box1.localToGlobal(Offset.zero).dy, -150.0);
    expect(box2.localToGlobal(Offset.zero).dy, 100.0);
    expect(box3.localToGlobal(Offset.zero).dy, 350.0);
  });

  testWidgets('Stretch overscroll works in reverse - vertical', (WidgetTester tester) async {
    final GlobalKey box1Key = GlobalKey();
    final GlobalKey box2Key = GlobalKey();
    final GlobalKey box3Key = GlobalKey();
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      buildTest(box1Key, box2Key, box3Key, controller, reverse: true),
    );

    expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
    expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
    final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
    final RenderBox box3 = tester.renderObject(find.byKey(box3Key));

    expect(controller.offset, 0.0);
    expect(box1.localToGlobal(Offset.zero), const Offset(0.0, 350.0));
    expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 100.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(0.0, -150.0));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll
    await gesture.moveBy(const Offset(0.0, -200.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero).dy, lessThan(350.0));
    expect(box2.localToGlobal(Offset.zero).dy, lessThan(100.0));
    expect(box3.localToGlobal(Offset.zero).dy, lessThan(-150.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.vertical.reverse.png'),
    );
  });

  testWidgets('Stretch overscroll works in reverse - horizontal', (WidgetTester tester) async {
    final GlobalKey box1Key = GlobalKey();
    final GlobalKey box2Key = GlobalKey();
    final GlobalKey box3Key = GlobalKey();
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
        buildTest(
          box1Key,
          box2Key,
          box3Key,
          controller,
          axis: Axis.horizontal,
          reverse: true,
        ),
    );

    expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
    expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
    final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
    final RenderBox box3 = tester.renderObject(find.byKey(box3Key));

    expect(controller.offset, 0.0);
    expect(box1.localToGlobal(Offset.zero), const Offset(500.0, 0.0));
    expect(box2.localToGlobal(Offset.zero), const Offset(200.0, 0.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(-100.0, 0.0));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll
    await gesture.moveBy(const Offset(-200.0, 0.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero).dx, lessThan(500.0));
    expect(box2.localToGlobal(Offset.zero).dx, lessThan(200.0));
    expect(box3.localToGlobal(Offset.zero).dx, lessThan(-100.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.horizontal.reverse.png'),
    );
  });

  testWidgets('Stretch overscroll horizontally', (WidgetTester tester) async {
    final GlobalKey box1Key = GlobalKey();
    final GlobalKey box2Key = GlobalKey();
    final GlobalKey box3Key = GlobalKey();
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      buildTest(box1Key, box2Key, box3Key, controller, axis: Axis.horizontal)
    );

    expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
    expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
    final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
    final RenderBox box3 = tester.renderObject(find.byKey(box3Key));

    expect(controller.offset, 0.0);
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(300.0, 0.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(600.0, 0.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.horizontal.start.png'),
    );

    TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll the start
    await gesture.moveBy(const Offset(200.0, 0.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero).dx, greaterThan(305.0));
    expect(box3.localToGlobal(Offset.zero).dx, greaterThan(610.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.horizontal.start.stretched.png'),
    );

    await gesture.up();
    await tester.pumpAndSettle();

    // Stretch released back to the start
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(300.0, 0.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(600.0, 0.0));

    // Jump to end of the list
    controller.jumpTo(controller.position.maxScrollExtent);
    await tester.pumpAndSettle();
    expect(controller.offset, 100.0);
    expect(box1.localToGlobal(Offset.zero).dx, -100.0);
    expect(box2.localToGlobal(Offset.zero).dx, 200.0);
    expect(box3.localToGlobal(Offset.zero).dx, 500.0);
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.horizontal.end.png'),
    );

    gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll the end
    await gesture.moveBy(const Offset(-200.0, 0.0));
    await tester.pumpAndSettle();
    expect(box1.localToGlobal(Offset.zero).dx, lessThan(-116.0));
    expect(box2.localToGlobal(Offset.zero).dx, lessThan(190.0));
    expect(box3.localToGlobal(Offset.zero).dx, lessThan(500.0));
    await expectLater(
      find.byType(CustomScrollView),
      matchesGoldenFile('overscroll_stretch.horizontal.end.stretched.png'),
    );

    await gesture.up();
    await tester.pumpAndSettle();

    // Stretch released back
    expect(box1.localToGlobal(Offset.zero).dx, -100.0);
    expect(box2.localToGlobal(Offset.zero).dx, 200.0);
    expect(box3.localToGlobal(Offset.zero).dx, 500.0);
  });

  testWidgets('Disallow stretching overscroll', (WidgetTester tester) async {
    final GlobalKey box1Key = GlobalKey();
    final GlobalKey box2Key = GlobalKey();
    final GlobalKey box3Key = GlobalKey();
    final ScrollController controller = ScrollController();
    double indicatorNotification =0;
    await tester.pumpWidget(
      NotificationListener<OverscrollIndicatorNotification>(
        onNotification: (OverscrollIndicatorNotification notification) {
          notification.disallowIndicator();
          indicatorNotification += 1;
          return false;
        },
        child: buildTest(box1Key, box2Key, box3Key, controller),
      )
    );

    expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
    expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    final RenderBox box1 = tester.renderObject(find.byKey(box1Key));
    final RenderBox box2 = tester.renderObject(find.byKey(box2Key));
    final RenderBox box3 = tester.renderObject(find.byKey(box3Key));

    expect(indicatorNotification, 0.0);
    expect(controller.offset, 0.0);
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 250.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(0.0, 500.0));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
    // Overscroll the start, should not stretch
    await gesture.moveBy(const Offset(0.0, 200.0));
    await tester.pumpAndSettle();
    expect(indicatorNotification, 1.0);
    expect(box1.localToGlobal(Offset.zero), Offset.zero);
    expect(box2.localToGlobal(Offset.zero), const Offset(0.0, 250.0));
    expect(box3.localToGlobal(Offset.zero), const Offset(0.0, 500.0));

    await gesture.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Stretch does not overflow bounds of container', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/90197
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(size: Size(800.0, 600.0)),
        child: ScrollConfiguration(
          behavior: const ScrollBehavior().copyWith(overscroll: false),
          child: Column(
            children: <Widget>[
              StretchingOverscrollIndicator(
                axisDirection: AxisDirection.down,
                child: SizedBox(
                  height: 300,
                  child: ListView.builder(
                    itemCount: 20,
                    itemBuilder: (BuildContext context, int index){
                      return Padding(
                          padding: const EdgeInsets.all(10.0),
                          child: Text('Index $index'),
                      );
                    },
                  ),
                ),
              ),
              Opacity(
                opacity: 0.5,
                child: Container(
                  color: const Color(0xD0FF0000),
                  height: 100,
                ),
              ),
            ],
          ),
        ),
      ),
    ));

    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, 51.0);

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Overscroll the start.
    await gesture.moveBy(const Offset(0.0, 200.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(0));
    // Image should not show the text overlapping the red area below the list.
    await expectLater(
      find.byType(Column),
      matchesGoldenFile('overscroll_stretch.no_overflow.png'),
    );

    await gesture.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Clip behavior is updated as needed', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/97867
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(size: Size(800.0, 600.0)),
          child: ScrollConfiguration(
            behavior: const ScrollBehavior().copyWith(overscroll: false),
            child: Column(
              children: <Widget>[
                StretchingOverscrollIndicator(
                  axisDirection: AxisDirection.down,
                  child: SizedBox(
                    height: 300,
                    child: ListView.builder(
                      itemCount: 20,
                      itemBuilder: (BuildContext context, int index){
                        return Padding(
                          padding: const EdgeInsets.all(10.0),
                          child: Text('Index $index'),
                        );
                      },
                    ),
                  ),
                ),
                Opacity(
                  opacity: 0.5,
                  child: Container(
                    color: const Color(0xD0FF0000),
                    height: 100,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, 51.0);
    RenderClipRect renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
    // Currently not clipping
    expect(renderClip.clipBehavior, equals(Clip.none));

    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Overscroll the start.
    await gesture.moveBy(const Offset(0.0, 200.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(0));
    renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
    // Now clipping
    expect(renderClip.clipBehavior, equals(Clip.hardEdge));

    await gesture.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Stretch limit', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/99264
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: ScrollConfiguration(
            behavior: const ScrollBehavior().copyWith(overscroll: false),
            child: StretchingOverscrollIndicator(
              axisDirection: AxisDirection.down,
              child: SizedBox(
                height: 300,
                child: ListView.builder(
                  itemCount: 20,
                  itemBuilder: (BuildContext context, int index){
                    return Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Text('Index $index'),
                    );
                  },
                ),
              ),
            ),
          ),
        )
      )
    );
    const double maxStretchLocation = 52.63178407049861;

    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, 51.0);

    TestGesture pointer = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Overscroll beyond the limit (the viewport is 600.0).
    await pointer.moveBy(const Offset(0.0, 610.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, maxStretchLocation);

    pointer = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Overscroll way way beyond the limit
    await pointer.moveBy(const Offset(0.0, 1000.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, maxStretchLocation);

    await pointer.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Multiple pointers wll not exceed stretch limit', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/99264
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: ScrollConfiguration(
            behavior: const ScrollBehavior().copyWith(overscroll: false),
            child: StretchingOverscrollIndicator(
              axisDirection: AxisDirection.down,
              child: SizedBox(
                height: 300,
                child: ListView.builder(
                  itemCount: 20,
                  itemBuilder: (BuildContext context, int index){
                    return Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Text('Index $index'),
                    );
                  },
                ),
              ),
            ),
          ),
        )
      )
    );
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, 51.0);

    final TestGesture pointer1 = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Overscroll the start.
    await pointer1.moveBy(const Offset(0.0, 210.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    double lastStretchedLocation = tester.getCenter(find.text('Index 1')).dy;
    expect(lastStretchedLocation, greaterThan(51.0));

    final TestGesture pointer2 = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Add overscroll from an additional pointer
    await pointer2.moveBy(const Offset(0.0, 210.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(lastStretchedLocation));
    lastStretchedLocation = tester.getCenter(find.text('Index 1')).dy;

    final TestGesture pointer3 = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Add overscroll from an additional pointer, exceeding the max stretch (600)
    await pointer3.moveBy(const Offset(0.0, 210.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(lastStretchedLocation));
    lastStretchedLocation = tester.getCenter(find.text('Index 1')).dy;

    final TestGesture pointer4 = await tester.startGesture(tester.getCenter(find.text('Index 1')));
    // Since we have maxed out the overscroll, it should not have stretched
    // further, regardless of the number of pointers.
    await pointer4.moveBy(const Offset(0.0, 210.0));
    await tester.pumpAndSettle();
    expect(find.text('Index 1'), findsOneWidget);
    expect(tester.getCenter(find.text('Index 1')).dy, lastStretchedLocation);

    await pointer1.up();
    await pointer2.up();
    await pointer3.up();
    await pointer4.up();
    await tester.pumpAndSettle();
  });
}
