// 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.

// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=382757700"
@Tags(<String>['no-shuffle'])

import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/mock_canvas.dart';

const Duration _kScrollbarFadeDuration = Duration(milliseconds: 300);
const Duration _kScrollbarTimeToFade = Duration(milliseconds: 600);
const Color _kAndroidThumbIdleColor = Color(0xffbcbcbc);
const Rect _kAndroidTrackDimensions = Rect.fromLTRB(796.0, 0.0, 800.0, 600.0);
const Radius _kDefaultThumbRadius = Radius.circular(8.0);
const Color _kDefaultIdleThumbColor = Color(0x1a000000);
const Offset _kTrackBorderPoint1 = Offset(796.0, 0.0);
const Offset _kTrackBorderPoint2 = Offset(796.0, 600.0);

Rect getStartingThumbRect({ required bool isAndroid }) {
  return isAndroid
    // On Android the thumb is slightly different. The thumb is only 4 pixels wide,
    // and has no margin along the side of the viewport.
    ? const Rect.fromLTRB(796.0, 0.0, 800.0, 90.0)
    // The Material Design thumb is 8 pixels wide, with a 2
    // pixel margin to the right edge of the viewport.
    : const Rect.fromLTRB(790.0, 0.0, 798.0, 90.0);
}

class TestCanvas implements Canvas {
  final List<Invocation> invocations = <Invocation>[];

  @override
  void noSuchMethod(Invocation invocation) {
    invocations.add(invocation);
  }
}

Widget _buildBoilerplate({
  TextDirection textDirection = TextDirection.ltr,
  EdgeInsets padding = EdgeInsets.zero,
  required Widget child,
}) {
  return Directionality(
    textDirection: textDirection,
    child: MediaQuery(
      data: MediaQueryData(padding: padding),
      child: ScrollConfiguration(
        behavior: const NoScrollbarBehavior(),
        child: child,
      ),
    ),
  );
}

class NoScrollbarBehavior extends MaterialScrollBehavior {
  const NoScrollbarBehavior();

  @override
  Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) => child;
}

void main() {
  testWidgets("Scrollbar doesn't show when tapping list", (WidgetTester tester) async {
    await tester.pumpWidget(
      _buildBoilerplate(
        child: Center(
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: const Color(0xFFFFFF00)),
            ),
            height: 200.0,
            width: 300.0,
            child: Scrollbar(
              child: ListView(
                children: const <Widget>[
                  SizedBox(height: 40.0, child: Text('0')),
                  SizedBox(height: 40.0, child: Text('1')),
                  SizedBox(height: 40.0, child: Text('2')),
                  SizedBox(height: 40.0, child: Text('3')),
                  SizedBox(height: 40.0, child: Text('4')),
                  SizedBox(height: 40.0, child: Text('5')),
                  SizedBox(height: 40.0, child: Text('6')),
                  SizedBox(height: 40.0, child: Text('7')),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    SchedulerBinding.instance!.debugAssertNoTransientCallbacks('Building a list with a scrollbar triggered an animation.');
    await tester.tap(find.byType(ListView));
    SchedulerBinding.instance!.debugAssertNoTransientCallbacks('Tapping a block with a scrollbar triggered an animation.');
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.drag(find.byType(ListView), const Offset(0.0, -10.0));
    expect(SchedulerBinding.instance!.transientCallbackCount, greaterThan(0));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));
  });

  testWidgets('ScrollbarPainter does not divide by zero', (WidgetTester tester) async {
    await tester.pumpWidget(
      _buildBoilerplate(child: SizedBox(
        height: 200.0,
        width: 300.0,
        child: Scrollbar(
          child: ListView(
            children: const <Widget>[
              SizedBox(height: 40.0, child: Text('0')),
            ],
          ),
        ),
      )),
    );

    final CustomPaint custom = tester.widget(find.descendant(
      of: find.byType(Scrollbar),
      matching: find.byType(CustomPaint),
    ).first);
    final ScrollbarPainter? scrollPainter = custom.foregroundPainter as ScrollbarPainter?;
    // Dragging makes the scrollbar first appear.
    await tester.drag(find.text('0'), const Offset(0.0, -10.0));
    await tester.pump(const Duration(milliseconds: 200));
    await tester.pump(const Duration(milliseconds: 200));

    final ScrollMetrics metrics = FixedScrollMetrics(
      minScrollExtent: 0.0,
      maxScrollExtent: 0.0,
      pixels: 0.0,
      viewportDimension: 100.0,
      axisDirection: AxisDirection.down,
    );
    // ignore: avoid_dynamic_calls
    scrollPainter!.update(metrics, AxisDirection.down);

    final TestCanvas canvas = TestCanvas();
    // ignore: avoid_dynamic_calls
    scrollPainter.paint(canvas, const Size(10.0, 100.0));

    // Scrollbar is not supposed to draw anything if there isn't enough content.
    expect(canvas.invocations.isEmpty, isTrue);
  });

  testWidgets(
    'When isAlwaysShown is true, must pass a controller or find PrimaryScrollController',
    (WidgetTester tester) async {
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: Theme(
            data: ThemeData(),
            child: const Scrollbar(
              isAlwaysShown: true,
              child: SingleChildScrollView(
                child: SizedBox(
                  width: 4000.0,
                  height: 4000.0,
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      final AssertionError exception = tester.takeException() as AssertionError;
      expect(exception, isAssertionError);
    },
  );

  testWidgets(
    'When isAlwaysShown is true, must pass a controller that is attached to a scroll view or find PrimaryScrollController',
    (WidgetTester tester) async {
      final ScrollController controller = ScrollController();
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: Theme(
            data: ThemeData(),
            child: Scrollbar(
              isAlwaysShown: true,
              controller: controller,
              child: const SingleChildScrollView(
                child: SizedBox(
                  width: 4000.0,
                  height: 4000.0,
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      final AssertionError exception = tester.takeException() as AssertionError;
      expect(exception, isAssertionError);
    },
  );

  testWidgets('On first render with isAlwaysShown: true, the thumb shows', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: true,
            controller: controller,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), paints..rect());
  });

  testWidgets('On first render with isAlwaysShown: true, the thumb shows with PrimaryScrollController', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: PrimaryScrollController(
            controller: controller,
            child: Builder(
              builder: (BuildContext context) {
                return const Scrollbar(
                  isAlwaysShown: true,
                  child: SingleChildScrollView(
                    primary: true,
                    child: SizedBox(
                      width: 4000.0,
                      height: 4000.0,
                    ),
                  ),
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), paints..rect());
  });

  testWidgets('On first render with isAlwaysShown: false, the thumb is hidden', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll() {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            isAlwaysShown: false,
            controller: controller,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 4000.0,
                height: 4000.0,
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll());
    await tester.pumpAndSettle();
    expect(find.byType(Scrollbar), isNot(paints..rect()));
  });

  testWidgets(
    'With isAlwaysShown: true, fling a scroll. While it is still scrolling, set isAlwaysShown: false. The thumb should not fade out until the scrolling stops.',
    (WidgetTester tester) async {
      final ScrollController controller = ScrollController();
      bool isAlwaysShown = true;
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Theme(
                data: ThemeData(),
                child: Scaffold(
                  floatingActionButton: FloatingActionButton(
                    child: const Icon(Icons.threed_rotation),
                    onPressed: () {
                      setState(() {
                        isAlwaysShown = !isAlwaysShown;
                      });
                    },
                  ),
                  body: Scrollbar(
                    isAlwaysShown: isAlwaysShown,
                    controller: controller,
                    child: SingleChildScrollView(
                      controller: controller,
                      child: const SizedBox(
                        width: 4000.0,
                        height: 4000.0,
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      await tester.pumpAndSettle();
      await tester.fling(
        find.byType(SingleChildScrollView),
        const Offset(0.0, -10.0),
        10,
      );
      expect(find.byType(Scrollbar), paints..rect());

      await tester.tap(find.byType(FloatingActionButton));
      await tester.pumpAndSettle();
      // Scrollbar is not showing after scroll finishes
      expect(find.byType(Scrollbar), isNot(paints..rect()));
    },
  );

  testWidgets(
    'With isAlwaysShown: false, set isAlwaysShown: true. The thumb should be always shown directly',
    (WidgetTester tester) async {
      final ScrollController controller = ScrollController();
      bool isAlwaysShown = false;
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Theme(
                data: ThemeData(),
                child: Scaffold(
                  floatingActionButton: FloatingActionButton(
                    child: const Icon(Icons.threed_rotation),
                    onPressed: () {
                      setState(() {
                        isAlwaysShown = !isAlwaysShown;
                      });
                    },
                  ),
                  body: Scrollbar(
                    isAlwaysShown: isAlwaysShown,
                    controller: controller,
                    child: SingleChildScrollView(
                      controller: controller,
                      child: const SizedBox(
                        width: 4000.0,
                        height: 4000.0,
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      await tester.pumpAndSettle();
      expect(find.byType(Scrollbar), isNot(paints..rect()));

      await tester.tap(find.byType(FloatingActionButton));
      await tester.pumpAndSettle();
      // Scrollbar is not showing after scroll finishes
      expect(find.byType(Scrollbar), paints..rect());
    },
  );

  testWidgets(
    'With isAlwaysShown: false, fling a scroll. While it is still scrolling, set isAlwaysShown: true. The thumb should not fade even after the scrolling stops',
    (WidgetTester tester) async {
      final ScrollController controller = ScrollController();
      bool isAlwaysShown = false;
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Theme(
                data: ThemeData(),
                child: Scaffold(
                  floatingActionButton: FloatingActionButton(
                    child: const Icon(Icons.threed_rotation),
                    onPressed: () {
                      setState(() {
                        isAlwaysShown = !isAlwaysShown;
                      });
                    },
                  ),
                  body: Scrollbar(
                    isAlwaysShown: isAlwaysShown,
                    controller: controller,
                    child: SingleChildScrollView(
                      controller: controller,
                      child: const SizedBox(
                        width: 4000.0,
                        height: 4000.0,
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      await tester.pumpAndSettle();
      expect(find.byType(Scrollbar), isNot(paints..rect()));
      await tester.fling(
        find.byType(SingleChildScrollView),
        const Offset(0.0, -10.0),
        10,
      );
      expect(find.byType(Scrollbar), paints..rect());

      await tester.tap(find.byType(FloatingActionButton));
      await tester.pump();
      expect(find.byType(Scrollbar), paints..rect());

      // Wait for the timer delay to expire.
      await tester.pump(const Duration(milliseconds: 600)); // _kScrollbarTimeToFade
      await tester.pumpAndSettle();
      // Scrollbar thumb is showing after scroll finishes and timer ends.
      expect(find.byType(Scrollbar), paints..rect());
    },
  );

  testWidgets(
    'Toggling isAlwaysShown while not scrolling fades the thumb in/out. This works even when you have never scrolled at all yet',
    (WidgetTester tester) async {
      final ScrollController controller = ScrollController();
      bool isAlwaysShown = true;
      Widget viewWithScroll() {
        return _buildBoilerplate(
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Theme(
                data: ThemeData(),
                child: Scaffold(
                  floatingActionButton: FloatingActionButton(
                    child: const Icon(Icons.threed_rotation),
                    onPressed: () {
                      setState(() {
                        isAlwaysShown = !isAlwaysShown;
                      });
                    },
                  ),
                  body: Scrollbar(
                    isAlwaysShown: isAlwaysShown,
                    controller: controller,
                    child: SingleChildScrollView(
                      controller: controller,
                      child: const SizedBox(
                        width: 4000.0,
                        height: 4000.0,
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        );
      }

      await tester.pumpWidget(viewWithScroll());
      await tester.pumpAndSettle();
      final Finder materialScrollbar = find.byType(Scrollbar);
      expect(materialScrollbar, paints..rect());

      await tester.tap(find.byType(FloatingActionButton));
      await tester.pumpAndSettle();
      expect(materialScrollbar, isNot(paints..rect()));
    },
  );

  testWidgets('Scrollbar respects thickness and radius', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll({Radius? radius}) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(),
          child: Scrollbar(
            controller: controller,
            thickness: 20,
            radius: radius,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(
                width: 1600.0,
                height: 1200.0,
              ),
            ),
          ),
        ),
      );
    }

    // Scroll a bit to cause the scrollbar thumb to be shown;
    // undo the scroll to put the thumb back at the top.
    await tester.pumpWidget(viewWithScroll());
    const double scrollAmount = 10.0;
    final TestGesture scrollGesture = await tester.startGesture(tester.getCenter(find.byType(SingleChildScrollView)));
    await scrollGesture.moveBy(const Offset(0.0, -scrollAmount));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    await scrollGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pump();
    await scrollGesture.up();
    await tester.pump();

    // Long press on the scrollbar thumb and expect it to grow
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(780.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(780.0, 0.0),
          p2: const Offset(780.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(780.0, 0.0, 800.0, 300.0),
          color: _kAndroidThumbIdleColor,
        ),
    );
    await tester.pumpWidget(viewWithScroll(radius: const Radius.circular(10)));
    expect(find.byType(Scrollbar), paints..rrect(
      rrect: RRect.fromRectAndRadius(const Rect.fromLTRB(780, 0.0, 800.0, 300.0), const Radius.circular(10)),
    ));

    await tester.pumpAndSettle();
  });

  testWidgets('Tapping the track area pages the Scroll View', (WidgetTester tester) async {
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: Scrollbar(
            interactive: true,
            isAlwaysShown: true,
            controller: scrollController,
            child: SingleChildScrollView(
              controller: scrollController,
              child: const SizedBox(width: 1000.0, height: 1000.0),
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 360.0),
          color: _kAndroidThumbIdleColor,
        ),
    );

    // Tap on the track area below the thumb.
    await tester.tapAt(const Offset(796.0, 550.0));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 400.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 240.0, 800.0, 600.0),
          color: _kAndroidThumbIdleColor,
        ),
    );

    // Tap on the track area above the thumb.
    await tester.tapAt(const Offset(796.0, 50.0));
    await tester.pumpAndSettle();

    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 360.0),
          color: _kAndroidThumbIdleColor,
        ),
    );
  });

  testWidgets('Scrollbar never goes away until finger lift', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scrollbar(
          child: SingleChildScrollView(
            child: SizedBox(width: 4000.0, height: 4000.0),
          ),
        ),
      ),
    );
    final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(SingleChildScrollView)));
    await gesture.moveBy(const Offset(0.0, -20.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 3.0, 800.0, 93.0),
          color: _kAndroidThumbIdleColor,
        ),
    );

    await tester.pump(const Duration(seconds: 3));
    await tester.pump(const Duration(seconds: 3));
    // Still there.
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 3.0, 800.0, 93.0),
          color: _kAndroidThumbIdleColor,
        ),
    );

    await gesture.up();
    await tester.pump(_kScrollbarTimeToFade);
    await tester.pump(_kScrollbarFadeDuration * 0.5);

    // Opacity going down now.
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 3.0, 800.0, 93.0),
          color: const Color(0xc6bcbcbc),
        ),
    );
  });

  testWidgets('Scrollbar thumb can be dragged', (WidgetTester tester) async {
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: PrimaryScrollController(
          controller: scrollController,
          child: Scrollbar(
            interactive: true,
            isAlwaysShown: true,
            controller: scrollController,
            child: const SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: getStartingThumbRect(isAndroid: true),
          color: _kAndroidThumbIdleColor,
        ),
    );

    // Drag the thumb down to scroll down.
    const double scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();

    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: getStartingThumbRect(isAndroid: true),
          // Drag color
          color: const Color(0x99000000),
        ),
    );

    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();

    // The view has scrolled more than it would have by a swipe pointer of the
    // same distance.
    expect(scrollController.offset, greaterThan(scrollAmount * 2));
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 10.0, 800.0, 100.0),
          color: _kAndroidThumbIdleColor,
        ),
    );
  });

  testWidgets('Scrollbar thumb color completes a hover animation', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(scrollbarTheme: const ScrollbarThemeData(isAlwaysShown: true)),
        home: const SingleChildScrollView(
          child: SizedBox(width: 4000.0, height: 4000.0),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(Scrollbar),
      paints..rrect(
        rrect: RRect.fromRectAndRadius(
          getStartingThumbRect(isAndroid: false),
          _kDefaultThumbRadius,
        ),
        color: _kDefaultIdleThumbColor,
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(794.0, 5.0));
    await tester.pumpAndSettle();

    expect(
      find.byType(Scrollbar),
      paints..rrect(
        rrect: RRect.fromRectAndRadius(
          getStartingThumbRect(isAndroid: false),
          _kDefaultThumbRadius,
        ),
        // Hover color
        color: const Color(0x80000000),
      ),
    );
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.linux,
      TargetPlatform.macOS,
      TargetPlatform.windows,
    }),
  );

  testWidgets('Hover animation is not triggered by tap gestures', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(scrollbarTheme: const ScrollbarThemeData(
          isAlwaysShown: true,
          showTrackOnHover: true,
        )),
        home: const SingleChildScrollView(
          child: SizedBox(width: 4000.0, height: 4000.0),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(Scrollbar),
      paints..rrect(
        rrect: RRect.fromRectAndRadius(
          getStartingThumbRect(isAndroid: false),
          _kDefaultThumbRadius,
        ),
        color: _kDefaultIdleThumbColor,
      ),
    );
    await tester.tapAt(const Offset(794.0, 5.0));
    await tester.pumpAndSettle();

    // Tapping triggers a hover enter event. In this case, the Scrollbar should
    // be unchanged since it ignores hover events that aren't from a mouse.
    expect(
      find.byType(Scrollbar),
      paints..rrect(
        rrect: RRect.fromRectAndRadius(
          getStartingThumbRect(isAndroid: false),
          _kDefaultThumbRadius,
        ),
        color: _kDefaultIdleThumbColor,
      ),
    );

    // Now trigger hover with a mouse.
    final TestGesture gesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(794.0, 5.0));
    await tester.pump();

    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(784.0, 0.0, 800.0, 600.0),
          color: const Color(0x08000000),
        )
        ..line(
          p1: const Offset(784.0, 0.0),
          p2: const Offset(784.0, 600.0),
          strokeWidth: 1.0,
          color: _kDefaultIdleThumbColor,
        )
        ..rrect(
          rrect: RRect.fromRectAndRadius(
            // Scrollbar thumb is larger
            const Rect.fromLTRB(786.0, 0.0, 798.0, 90.0),
            _kDefaultThumbRadius,
          ),
          // Hover color
          color: const Color(0x80000000),
        ),
    );
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.linux }),
  );

  testWidgets('Scrollbar showTrackOnHover', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(scrollbarTheme: const ScrollbarThemeData(
          isAlwaysShown: true,
          showTrackOnHover: true,
        )),
        home: const SingleChildScrollView(
          child: SizedBox(width: 4000.0, height: 4000.0),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(
      find.byType(Scrollbar),
      paints..rrect(
        rrect: RRect.fromRectAndRadius(
          getStartingThumbRect(isAndroid: false),
          _kDefaultThumbRadius,
        ),
        color: _kDefaultIdleThumbColor,
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: ui.PointerDeviceKind.mouse);
    await gesture.addPointer();
    addTearDown(gesture.removePointer);
    await gesture.moveTo(const Offset(794.0, 5.0));
    await tester.pump();

    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(784.0, 0.0, 800.0, 600.0),
          color: const Color(0x08000000),
        )
        ..line(
          p1: const Offset(784.0, 0.0),
          p2: const Offset(784.0, 600.0),
          strokeWidth: 1.0,
          color: _kDefaultIdleThumbColor,
        )
        ..rrect(
          rrect: RRect.fromRectAndRadius(
            // Scrollbar thumb is larger
            const Rect.fromLTRB(786.0, 0.0, 798.0, 90.0),
            _kDefaultThumbRadius,
          ),
          // Hover color
          color: const Color(0x80000000),
      ),
    );
  },
    variant: const TargetPlatformVariant(<TargetPlatform>{
      TargetPlatform.linux,
      TargetPlatform.macOS,
      TargetPlatform.windows,
    }),
  );

  testWidgets('Adaptive scrollbar', (WidgetTester tester) async {
    Widget viewWithScroll(TargetPlatform platform) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(
            platform: platform,
          ),
          child: const Scrollbar(
            child: SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll(TargetPlatform.android));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    // Scrollbar fully showing
    await tester.pump(const Duration(milliseconds: 500));
    expect(find.byType(Scrollbar), paints..rect());

    await tester.pumpWidget(viewWithScroll(TargetPlatform.iOS));
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -10.0));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.byType(Scrollbar), paints..rrect());
    expect(find.byType(CupertinoScrollbar), paints..rrect());
    await gesture.up();
    await tester.pumpAndSettle();
  });

  testWidgets('Scrollbar passes controller to CupertinoScrollbar', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    Widget viewWithScroll(TargetPlatform? platform) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(
            platform: platform,
          ),
          child: Scrollbar(
            controller: controller,
            child: SingleChildScrollView(
              controller: controller,
              child: const SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(viewWithScroll(debugDefaultTargetPlatformOverride));
    final TestGesture gesture = await tester.startGesture(
      tester.getCenter(find.byType(SingleChildScrollView)),
    );
    await gesture.moveBy(const Offset(0.0, -10.0));
    await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.byType(CupertinoScrollbar), paints..rrect());
    final CupertinoScrollbar scrollbar = tester.widget<CupertinoScrollbar>(find.byType(CupertinoScrollbar));
    expect(scrollbar.controller, isNotNull);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));

  testWidgets("Scrollbar doesn't show when scroll the inner scrollable widget", (WidgetTester tester) async {
    final GlobalKey key1 = GlobalKey();
    final GlobalKey key2 = GlobalKey();
    final GlobalKey outerKey = GlobalKey();
    final GlobalKey innerKey = GlobalKey();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: ScrollConfiguration(
            behavior: const NoScrollbarBehavior(),
            child: Scrollbar(
              key: key2,
              child: SingleChildScrollView(
                key: outerKey,
                child: SizedBox(
                  height: 1000.0,
                  width: double.infinity,
                  child: Column(
                    children: <Widget>[
                      Scrollbar(
                        key: key1,
                        child: SizedBox(
                          height: 300.0,
                          width: double.infinity,
                          child: SingleChildScrollView(
                            key: innerKey,
                            child: const SizedBox(
                              key: Key('Inner scrollable'),
                              height: 1000.0,
                              width: double.infinity,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );

    // Drag the inner scrollable widget.
    await tester.drag(find.byKey(innerKey), const Offset(0.0, -25.0));
    await tester.pump();
    // Scrollbar fully showing.
    await tester.pump(const Duration(milliseconds: 500));

    expect(
      tester.renderObject(find.byKey(key2)),
      paintsExactlyCountTimes(#drawRect, 2), // Each bar will call [drawRect] twice.
    );

    expect(
      tester.renderObject(find.byKey(key1)),
      paintsExactlyCountTimes(#drawRect, 2),
    );
  }, variant: TargetPlatformVariant.all());

  testWidgets('Scrollbar dragging can be disabled', (WidgetTester tester) async {
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: PrimaryScrollController(
          controller: scrollController,
          child: Scrollbar(
            interactive: false,
            isAlwaysShown: true,
            controller: scrollController,
            child: const SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(788.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(788.0, 0.0),
          p2: const Offset(788.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rrect(
          rrect: RRect.fromRectAndRadius(
            getStartingThumbRect(isAndroid: false),
            _kDefaultThumbRadius,
          ),
          color: _kDefaultIdleThumbColor,
        ),
    );

    // Try to drag the thumb down.
    const double scrollAmount = 10.0;
    final TestGesture dragScrollbarThumbGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();
    await dragScrollbarThumbGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    await dragScrollbarThumbGesture.up();
    await tester.pumpAndSettle();
    // Dragging on the thumb does not change the offset.
    expect(scrollController.offset, 0.0);

    // Drag in the track area to validate pass through to scrollable.
    final TestGesture dragPassThroughTrack = await tester.startGesture(const Offset(797.0, 250.0));
    await dragPassThroughTrack.moveBy(const Offset(0.0, -scrollAmount));
    await tester.pumpAndSettle();
    await dragPassThroughTrack.up();
    await tester.pumpAndSettle();
    // The scroll view received the drag.
    expect(scrollController.offset, scrollAmount);

    // Tap on the track to validate the scroll view will not page.
    await tester.tapAt(const Offset(797.0, 200.0));
    await tester.pumpAndSettle();
    // The offset should not have changed.
    expect(scrollController.offset, scrollAmount);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.fuchsia }));

  testWidgets('Scrollbar dragging is disabled by default on Android', (WidgetTester tester) async {
    int tapCount = 0;
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: PrimaryScrollController(
          controller: scrollController,
          child: Scrollbar(
            isAlwaysShown: true,
            controller: scrollController,
            child: SingleChildScrollView(
              dragStartBehavior: DragStartBehavior.down,
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () {
                  tapCount += 1;
                },
                child: const SizedBox(
                  width: 4000.0,
                  height: 4000.0,
                ),
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: getStartingThumbRect(isAndroid: true),
          color: _kAndroidThumbIdleColor,
        ),
    );

    // Try to drag the thumb down.
    const double scrollAmount = 50.0;
    await tester.dragFrom(
      const Offset(797.0, 45.0),
      const Offset(0.0, scrollAmount),
      touchSlopY: 0.0,
    );
    await tester.pumpAndSettle();
    // Dragging on the thumb does not change the offset.
    expect(scrollController.offset, 0.0);
    expect(tapCount, 0);

    // Try to drag up in the thumb area to validate pass through to scrollable.
    await tester.dragFrom(
      const Offset(797.0, 45.0),
      const Offset(0.0, -scrollAmount),
    );
    await tester.pumpAndSettle();
    // The scroll view received the drag.
    expect(scrollController.offset, scrollAmount);
    expect(tapCount, 0);

    // Drag in the track area to validate pass through to scrollable.
    await tester.dragFrom(
      const Offset(797.0, 45.0),
      const Offset(0.0, -scrollAmount),
      touchSlopY: 0.0,
    );
    await tester.pumpAndSettle();
    // The scroll view received the drag.
    expect(scrollController.offset, scrollAmount * 2);
    expect(tapCount, 0);

    // Tap on the thumb to validate the scroll view receives a click.
    await tester.tapAt(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();
    expect(tapCount, 1);

    // Tap on the track to validate the scroll view will not page and receives a click.
    await tester.tapAt(const Offset(797.0, 400.0));
    await tester.pumpAndSettle();
    // The offset should not have changed.
    expect(scrollController.offset, scrollAmount * 2);
    expect(tapCount, 2);
  });

  testWidgets('Simultaneous dragging and pointer scrolling does not cause a crash', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/70105
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: PrimaryScrollController(
          controller: scrollController,
          child: Scrollbar(
            interactive: true,
            isAlwaysShown: true,
            controller: scrollController,
            child: const SingleChildScrollView(
              child: SizedBox(width: 4000.0, height: 4000.0),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: getStartingThumbRect(isAndroid: true),
          color: _kAndroidThumbIdleColor,
        ),
    );

    // Drag the thumb down to scroll down.
    const double scrollAmount = 10.0;
    final TestGesture dragScrollbarGesture = await tester.startGesture(const Offset(797.0, 45.0));
    await tester.pumpAndSettle();

    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: _kAndroidTrackDimensions,
          color: Colors.transparent,
        )
        ..line(
          p1: _kTrackBorderPoint1,
          p2: _kTrackBorderPoint2,
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: getStartingThumbRect(isAndroid: true),
          // Drag color
          color: const Color(0x99000000),
        ),
    );

    await dragScrollbarGesture.moveBy(const Offset(0.0, scrollAmount));
    await tester.pumpAndSettle();
    expect(scrollController.offset, greaterThan(10.0));
    final double previousOffset = scrollController.offset;
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 10.0, 800.0, 100.0),
          color: const Color(0x99000000),
        ),
    );

    // Execute a pointer scroll while dragging (drag gesture has not come up yet)
    final TestPointer pointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    pointer.hover(const Offset(798.0, 15.0));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, 20.0)));
    await tester.pumpAndSettle();
    // Scrolling while holding the drag on the scrollbar and still hovered over
    // the scrollbar should not have changed the scroll offset.
    expect(pointer.location, const Offset(798.0, 15.0));
    expect(scrollController.offset, previousOffset);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 10.0, 800.0, 100.0),
          color: const Color(0x99000000),
        ),
    );

    // Drag is still being held, move pointer to be hovering over another area
    // of the scrollable (not over the scrollbar) and execute another pointer scroll
    pointer.hover(tester.getCenter(find.byType(SingleChildScrollView)));
    await tester.sendEventToBinding(pointer.scroll(const Offset(0.0, -70.0)));
    await tester.pumpAndSettle();
    // Scrolling while holding the drag on the scrollbar changed the offset
    expect(pointer.location, const Offset(400.0, 300.0));
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 90.0),
          color: const Color(0x99000000),
        ),
    );

    await dragScrollbarGesture.up();
    await tester.pumpAndSettle();
    expect(scrollController.offset, 0.0);
    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(796.0, 0.0),
          p2: const Offset(796.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(796.0, 0.0, 800.0, 90.0),
          color: const Color(0xffbcbcbc),
        ),
    );
  });

  testWidgets('Scrollbar.isAlwaysShown triggers assertion when multiple ScrollPositions are attached.', (WidgetTester tester) async {
    Widget _getTabContent({ ScrollController? scrollController }) {
      return Scrollbar(
        isAlwaysShown: true,
        controller: scrollController,
        child: ListView.builder(
          controller: scrollController,
          itemCount: 200,
          itemBuilder: (BuildContext context, int index) => const Text('Test'),
        ),
      );
    }

    Widget _buildApp({
      required String id,
      ScrollController? scrollController,
    }) {
      return MaterialApp(
        key: ValueKey<String>(id),
        home: DefaultTabController(
          length: 2,
          child: Scaffold(
            body: TabBarView(
              children: <Widget>[
                _getTabContent(scrollController: scrollController),
                _getTabContent(scrollController: scrollController),
              ],
            ),
          ),
        ),
      );
    }

    // Asserts when using the PrimaryScrollController.
    await tester.pumpWidget(_buildApp(id: 'PrimaryScrollController'));

    // Swipe to the second tab, resulting in two attached ScrollPositions during
    // the transition.
    await tester.drag(find.text('Test').first, const Offset(-100.0, 0.0));
    await tester.pump();

    FlutterError error = tester.takeException() as FlutterError;
    expect(
      error.message,
      contains('The PrimaryScrollController is currently attached to more than one ScrollPosition.'),
    );

    // Asserts when using the ScrollController provided by the user.
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(
      _buildApp(
        id: 'Provided ScrollController',
        scrollController: scrollController,
      ),
    );

    // Swipe to the second tab, resulting in two attached ScrollPositions during
    // the transition.
    await tester.drag(find.text('Test').first, const Offset(-100.0, 0.0));
    await tester.pump();
    error = tester.takeException() as FlutterError;
    expect(
      error.message,
      contains('The provided ScrollController is currently attached to more than one ScrollPosition.'),
    );
  });

  testWidgets('Scrollbar scrollOrientation works correctly', (WidgetTester tester) async {
    final ScrollController scrollController = ScrollController();

    Widget _buildScrollWithOrientation(ScrollbarOrientation orientation) {
      return _buildBoilerplate(
        child: Theme(
          data: ThemeData(
            platform: TargetPlatform.android,
          ),
          child: PrimaryScrollController(
            controller: scrollController,
            child: Scrollbar(
              interactive: true,
              isAlwaysShown: true,
              scrollbarOrientation: orientation,
              controller: scrollController,
              child: const SingleChildScrollView(
                child: SizedBox(width: 4000.0, height: 4000.0)
              ),
            ),
          ),
        )
      );
    }

    await tester.pumpWidget(_buildScrollWithOrientation(ScrollbarOrientation.left));
    await tester.pumpAndSettle();

    expect(
      find.byType(Scrollbar),
      paints
        ..rect(
          rect: const Rect.fromLTRB(0.0, 0.0, 4.0, 600.0),
          color: Colors.transparent,
        )
        ..line(
          p1: const Offset(4.0, 0.0),
          p2: const Offset(4.0, 600.0),
          strokeWidth: 1.0,
          color: Colors.transparent,
        )
        ..rect(
          rect: const Rect.fromLTRB(0.0, 0.0, 4.0, 90.0),
          color: _kAndroidThumbIdleColor,
        ),
    );
  });
}
