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

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('SliverList reverse children (with keys)', (WidgetTester tester) async {
    final List<int> items = List<int>.generate(20, (int i) => i);
    const double itemHeight = 300.0;
    const double viewportHeight = 500.0;

    const double scrollPosition = 18 * itemHeight;
    final ScrollController controller = ScrollController(initialScrollOffset: scrollPosition);

    await tester.pumpWidget(_buildSliverList(
      items: items,
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    await tester.pumpAndSettle();

    expect(controller.offset, scrollPosition);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);

    await tester.pumpWidget(_buildSliverList(
      items: items.reversed.toList(),
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    final int frames = await tester.pumpAndSettle();
    expect(frames, 1); // ensures that there is no (animated) bouncing of the scrollable

    expect(controller.offset, scrollPosition);
    expect(find.text('Tile 19'), findsNothing);
    expect(find.text('Tile 18'), findsNothing);
    expect(find.text('Tile 1'), findsOneWidget);
    expect(find.text('Tile 0'), findsOneWidget);

    controller.jumpTo(0.0);
    await tester.pumpAndSettle();

    expect(controller.offset, 0.0);
    expect(find.text('Tile 19'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 0'), findsNothing);
  });

  testWidgets('SliverList replace children (with keys)', (WidgetTester tester) async {
    final List<int> items = List<int>.generate(20, (int i) => i);
    const double itemHeight = 300.0;
    const double viewportHeight = 500.0;

    const double scrollPosition = 18 * itemHeight;
    final ScrollController controller = ScrollController(initialScrollOffset: scrollPosition);

    await tester.pumpWidget(_buildSliverList(
      items: items,
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    await tester.pumpAndSettle();

    expect(controller.offset, scrollPosition);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);

    await tester.pumpWidget(_buildSliverList(
      items: items.map<int>((int i) => i + 100).toList(),
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    final int frames = await tester.pumpAndSettle();
    expect(frames, 1); // ensures that there is no (animated) bouncing of the scrollable

    expect(controller.offset, scrollPosition);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 18'), findsNothing);
    expect(find.text('Tile 19'), findsNothing);

    expect(find.text('Tile 100'), findsNothing);
    expect(find.text('Tile 101'), findsNothing);
    expect(find.text('Tile 118'), findsOneWidget);
    expect(find.text('Tile 119'), findsOneWidget);

    controller.jumpTo(0.0);
    await tester.pumpAndSettle();

    expect(controller.offset, 0.0);
    expect(find.text('Tile 100'), findsOneWidget);
    expect(find.text('Tile 101'), findsOneWidget);
    expect(find.text('Tile 118'), findsNothing);
    expect(find.text('Tile 119'), findsNothing);
  });

  testWidgets('SliverList replace with shorter children list (with keys)', (WidgetTester tester) async {
    final List<int> items = List<int>.generate(20, (int i) => i);
    const double itemHeight = 300.0;
    const double viewportHeight = 500.0;

    final double scrollPosition = items.length * itemHeight - viewportHeight;
    final ScrollController controller = ScrollController(initialScrollOffset: scrollPosition);

    await tester.pumpWidget(_buildSliverList(
      items: items,
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    await tester.pumpAndSettle();

    expect(controller.offset, scrollPosition);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 17'), findsNothing);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);

    await tester.pumpWidget(_buildSliverList(
      items: items.sublist(0, items.length - 1),
      controller: controller,
      itemHeight: itemHeight,
      viewportHeight: viewportHeight,
    ));
    final int frames = await tester.pumpAndSettle();
    expect(frames, 1); // No animation when content shrinks suddenly.

    expect(controller.offset, scrollPosition - itemHeight);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 1'), findsNothing);
    expect(find.text('Tile 17'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsNothing);
  });

  testWidgets('SliverList should layout first child in case of child reordering', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/35904.
    List<String> items = <String>['1', '2'];

    await tester.pumpWidget(_buildSliverListRenderWidgetChild(items));
    await tester.pumpAndSettle();

    expect(find.text('Tile 1'), findsOneWidget);
    expect(find.text('Tile 2'), findsOneWidget);

    items = items.reversed.toList();
    await tester.pumpWidget(_buildSliverListRenderWidgetChild(items));
    await tester.pumpAndSettle();

    expect(find.text('Tile 1'), findsOneWidget);
    expect(find.text('Tile 2'), findsOneWidget);
  });

  testWidgets('SliverList should recalculate inaccurate layout offset case 1', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/42142.
    final List<int> items = List<int>.generate(20, (int i) => i);
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      _buildSliverList(
        items: List<int>.from(items),
        controller: controller,
        itemHeight: 50,
        viewportHeight: 200,
      ),
    );
    await tester.pumpAndSettle();

    await tester.drag(find.text('Tile 2'), const Offset(0.0, -1000.0));
    await tester.pumpAndSettle();

    // Viewport should be scrolled to the end of list.
    expect(controller.offset, 800.0);
    expect(find.text('Tile 15'), findsNothing);
    expect(find.text('Tile 16'), findsOneWidget);
    expect(find.text('Tile 17'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);

    // Prepends item to the list.
    items.insert(0, -1);
    await tester.pumpWidget(
      _buildSliverList(
        items: List<int>.from(items),
        controller: controller,
        itemHeight: 50,
        viewportHeight: 200,
      ),
    );
    await tester.pump();
    // We need second pump to ensure the scheduled animation gets run.
    await tester.pumpAndSettle();
    // Scroll offset should stay the same, and the items in viewport should be
    // shifted by one.
    expect(controller.offset, 800.0);
    expect(find.text('Tile 14'), findsNothing);
    expect(find.text('Tile 15'), findsOneWidget);
    expect(find.text('Tile 16'), findsOneWidget);
    expect(find.text('Tile 17'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsNothing);

    // Drags back to beginning and newly added item is visible.
    await tester.drag(find.text('Tile 16'), const Offset(0.0, 1000.0));
    await tester.pumpAndSettle();
    expect(controller.offset, 0.0);
    expect(find.text('Tile -1'), findsOneWidget);
    expect(find.text('Tile 0'), findsOneWidget);
    expect(find.text('Tile 1'), findsOneWidget);
    expect(find.text('Tile 2'), findsOneWidget);
    expect(find.text('Tile 3'), findsNothing);

  });

  testWidgets('SliverList should recalculate inaccurate layout offset case 2', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/42142.
    final List<int> items = List<int>.generate(20, (int i) => i);
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      _buildSliverList(
        items: List<int>.from(items),
        controller: controller,
        itemHeight: 50,
        viewportHeight: 200,
      ),
    );
    await tester.pumpAndSettle();

    await tester.drag(find.text('Tile 2'), const Offset(0.0, -1000.0));
    await tester.pumpAndSettle();

    // Viewport should be scrolled to the end of list.
    expect(controller.offset, 800.0);
    expect(find.text('Tile 15'), findsNothing);
    expect(find.text('Tile 16'), findsOneWidget);
    expect(find.text('Tile 17'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);

    // Reorders item to the front. This should make item 19 to be first child
    // with layout offset = null.
    final int swap = items[19];
    items[19] = items[3];
    items[3] = swap;

    await tester.pumpWidget(
      _buildSliverList(
        items: List<int>.from(items),
        controller: controller,
        itemHeight: 50,
        viewportHeight: 200,
      ),
    );
    await tester.pump();
    // We need second pump to ensure the scheduled animation gets run.
    await tester.pumpAndSettle();
    // Scroll offset should stay the same
    expect(controller.offset, 800.0);
    expect(find.text('Tile 14'), findsNothing);
    expect(find.text('Tile 15'), findsNothing);
    expect(find.text('Tile 16'), findsOneWidget);
    expect(find.text('Tile 17'), findsOneWidget);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 3'), findsOneWidget);
  });

  testWidgets('SliverList should start to perform layout from the initial child when there is no valid offset', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/66198.
    bool isShow = true;
    final ScrollController controller = ScrollController();
    Widget buildSliverList(ScrollController controller) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            height: 200,
            child: ListView(
              controller: controller,
              children: <Widget>[
                if (isShow)
                  for (int i = 0; i < 20; i++)
                    SizedBox(
                      height: 50,
                      child: Text('Tile $i'),
                    ),
                const SizedBox(), // Use this widget to occupy the position where the offset is 0 when rebuild
                const SizedBox(key: Key('key0'), height: 50.0),
                const SizedBox(key: Key('key1'), height: 50.0),
              ],
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildSliverList(controller));
    await tester.pumpAndSettle();

    // Scrolling to the bottom.
    await tester.drag(find.text('Tile 2'), const Offset(0.0, -1000.0));
    await tester.pumpAndSettle();

    // Viewport should be scrolled to the end of list.
    expect(controller.offset, 900.0);
    expect(find.text('Tile 17'), findsNothing);
    expect(find.text('Tile 18'), findsOneWidget);
    expect(find.text('Tile 19'), findsOneWidget);
    expect(find.byKey(const Key('key0')), findsOneWidget);
    expect(find.byKey(const Key('key1')), findsOneWidget);

    // Trigger rebuild.
    isShow = false;
    await tester.pumpWidget(buildSliverList(controller));

    // After rebuild, [ContainerRenderObjectMixin] has two children, and
    // neither of them has a valid layout offset.
    // SliverList can layout normally without any assert or dead loop.
    // Only the 'SizeBox' show in the viewport.
    expect(controller.offset, 0.0);
    expect(find.text('Tile 0'), findsNothing);
    expect(find.text('Tile 19'), findsNothing);
    expect(find.byKey(const Key('key0')), findsOneWidget);
    expect(find.byKey(const Key('key1')), findsOneWidget);
  });
}

Widget _buildSliverListRenderWidgetChild(List<String> items) {
  return MaterialApp(
    home: Directionality(
      textDirection: TextDirection.ltr,
      child: Material(
        child: SizedBox(
          height: 500,
          child: CustomScrollView(
            controller: ScrollController(),
            slivers: <Widget>[
              SliverList(
                delegate: SliverChildListDelegate(
                  items.map<Widget>((String item) {
                    return Chip(
                      key: Key(item),
                      label: Text('Tile $item'),
                    );
                  }).toList(),
                ),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

Widget _buildSliverList({
  List<int> items = const <int>[],
  ScrollController? controller,
  double itemHeight = 500.0,
  double viewportHeight = 300.0,
}) {
  return Directionality(
    textDirection: TextDirection.ltr,
    child: Center(
      child: SizedBox(
        height: viewportHeight,
        child: CustomScrollView(
          controller: controller,
          slivers: <Widget>[
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int i) {
                  return SizedBox(
                    key: ValueKey<int>(items[i]),
                    height: itemHeight,
                    child: Text('Tile ${items[i]}'),
                  );
                },
                findChildIndexCallback: (Key key) {
                  final ValueKey<int> valueKey = key as ValueKey<int>;
                  final int index = items.indexOf(valueKey.value);
                  return index == -1 ? null : index;
                },
                childCount: items.length,
              ),
            ),
          ],
        ),
      ),
    ),
  );
}
