// 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_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

import 'test_widgets.dart';

void main() {
  testWidgets('ListView mount/dismount smoke test', (WidgetTester tester) async {
    final List<int> callbackTracker = <int>[];

    // the root view is 800x600 in the test environment
    // so if our widget is 100 pixels tall, it should fit exactly 6 times.

    Widget builder() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: FlipWidget(
          left: ListView.builder(
            itemBuilder: (BuildContext context, int index) {
              callbackTracker.add(index);
              return Container(
                key: ValueKey<int>(index),
                height: 100.0,
                child: Text('$index'),
              );
            },
          ),
          right: const Text('Not Today'),
        ),
      );
    }

    await tester.pumpWidget(builder());

    final FlipWidgetState testWidget = tester.state(find.byType(FlipWidget));

    expect(callbackTracker, equals(<int>[
      0, 1, 2, 3, 4, 5, // visible
      6, 7, 8, // in cached area
    ]));

    callbackTracker.clear();
    testWidget.flip();
    await tester.pump();

    expect(callbackTracker, equals(<int>[]));

    callbackTracker.clear();
    testWidget.flip();
    await tester.pump();

    expect(callbackTracker, equals(<int>[
      0, 1, 2, 3, 4, 5, // visible
      6, 7, 8, // in cached area
    ]));
  });

  testWidgets('ListView vertical', (WidgetTester tester) async {
    final List<int> callbackTracker = <int>[];

    // the root view is 800x600 in the test environment
    // so if our widget is 200 pixels tall, it should fit exactly 3 times.
    // but if we are offset by 300 pixels, there will be 4, numbered 1-4.

    final IndexedWidgetBuilder itemBuilder = (BuildContext context, int index) {
      callbackTracker.add(index);
      return Container(
        key: ValueKey<int>(index),
        width: 500.0, // this should be ignored
        height: 200.0,
        child: Text('$index', textDirection: TextDirection.ltr),
      );
    };

    Widget builder() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: FlipWidget(
          left: ListView.builder(
            controller: ScrollController(initialScrollOffset: 300.0),
            itemBuilder: itemBuilder,
          ),
          right: const Text('Not Today'),
        ),
      );
    }

    await tester.pumpWidget(builder());

    // 0 is built to find its height
    expect(callbackTracker, equals(<int>[
      0, 1, 2, 3, 4,
      5, // in cached area
    ]));
    callbackTracker.clear();

    final ScrollableState scrollable = tester.state(find.byType(Scrollable));
    scrollable.position.jumpTo(600.0); // now only 3 should fit, numbered 3-5.

    await tester.pumpWidget(builder());

    // We build the visible children to find their new size.
    expect(callbackTracker, equals(<int>[
      0, 1, 2,
      3, 4, 5, //visible
      6, 7,
    ]));
    callbackTracker.clear();

    await tester.pumpWidget(builder());

    // 0 isn't built because they're not visible.
    expect(callbackTracker, equals(<int>[
      1, 2,
      3, 4, 5, // visible
      6, 7,
    ]));
    callbackTracker.clear();
  });

  testWidgets('ListView horizontal', (WidgetTester tester) async {
    final List<int> callbackTracker = <int>[];

    // the root view is 800x600 in the test environment
    // so if our widget is 200 pixels wide, it should fit exactly 4 times.
    // but if we are offset by 300 pixels, there will be 5, numbered 1-5.

    final IndexedWidgetBuilder itemBuilder = (BuildContext context, int index) {
      callbackTracker.add(index);
      return Container(
        key: ValueKey<int>(index),
        height: 500.0, // this should be ignored
        width: 200.0,
        child: Text('$index', textDirection: TextDirection.ltr),
      );
    };

    Widget builder() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: FlipWidget(
          left: ListView.builder(
            scrollDirection: Axis.horizontal,
            controller: ScrollController(initialScrollOffset: 500.0),
            itemBuilder: itemBuilder,
          ),
          right: const Text('Not Today'),
        ),
      );
    }

    await tester.pumpWidget(builder());

    // 0 is built to find its width
    expect(callbackTracker, equals(<int>[0, 1, 2, 3, 4, 5, 6, 7]));

    callbackTracker.clear();

    final ScrollableState scrollable = tester.state(find.byType(Scrollable));
    scrollable.position.jumpTo(600.0); // now only 4 should fit, numbered 2-5.

    await tester.pumpWidget(builder());

    // We build the visible children to find their new size.
    expect(callbackTracker, equals(<int>[1, 2, 3, 4, 5, 6, 7, 8]));
    callbackTracker.clear();

    await tester.pumpWidget(builder());

    // 0 isn't built because they're not visible.
    expect(callbackTracker, equals(<int>[1, 2, 3, 4, 5, 6, 7, 8]));
    callbackTracker.clear();
  });

  testWidgets('ListView reinvoke builders', (WidgetTester tester) async {
    final List<int> callbackTracker = <int>[];
    final List<String> text = <String>[];

    final IndexedWidgetBuilder itemBuilder = (BuildContext context, int index) {
      callbackTracker.add(index);
      return Container(
        key: ValueKey<int>(index),
        width: 500.0, // this should be ignored
        height: 220.0,
        child: Text('$index', textDirection: TextDirection.ltr),
      );
    };

    void collectText(Widget widget) {
      if (widget is Text)
        text.add(widget.data);
    }

    Widget builder() {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: ListView.builder(
          itemBuilder: itemBuilder,
        ),
      );
    }

    await tester.pumpWidget(builder());

    expect(callbackTracker, equals(<int>[
      0, 1, 2,
      3, // in cached area
    ]));
    callbackTracker.clear();
    tester.allWidgets.forEach(collectText);
    expect(text, equals(<String>['0', '1', '2', '3']));
    text.clear();

    await tester.pumpWidget(builder());

    expect(callbackTracker, equals(<int>[
      0, 1, 2,
      3, // in cached area
    ]));
    callbackTracker.clear();
    tester.allWidgets.forEach(collectText);
    expect(text, equals(<String>['0', '1', '2', '3']));
    text.clear();
  });

  testWidgets('ListView reinvoke builders', (WidgetTester tester) async {
    StateSetter setState;
    ThemeData themeData = ThemeData.light();

    final IndexedWidgetBuilder itemBuilder = (BuildContext context, int index) {
      return Container(
        key: ValueKey<int>(index),
        width: 500.0, // this should be ignored
        height: 220.0,
        color: Theme.of(context).primaryColor,
        child: Text('$index', textDirection: TextDirection.ltr),
      );
    };

    final Widget viewport = ListView.builder(
      itemBuilder: itemBuilder,
    );

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setter) {
            setState = setter;
            return Theme(data: themeData, child: viewport);
          },
        ),
      ),
    );

    Container widget = tester.firstWidget(find.byType(Container));
    expect(widget.color, equals(Colors.blue));

    setState(() {
      themeData = ThemeData(primarySwatch: Colors.green);
    });

    await tester.pump();

    widget = tester.firstWidget(find.byType(Container));
    expect(widget.color, equals(Colors.green));
  });

  testWidgets('ListView padding', (WidgetTester tester) async {
    final IndexedWidgetBuilder itemBuilder = (BuildContext context, int index) {
      return Container(
        key: ValueKey<int>(index),
        width: 500.0, // this should be ignored
        height: 220.0,
        color: Colors.green[500],
        child: Text('$index', textDirection: TextDirection.ltr),
      );
    };

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView.builder(
          padding: const EdgeInsets.fromLTRB(7.0, 3.0, 5.0, 11.0),
          itemBuilder: itemBuilder,
        ),
      ),
    );

    final RenderBox firstBox = tester.renderObject(find.text('0'));
    final Offset upperLeft = firstBox.localToGlobal(Offset.zero);
    expect(upperLeft, equals(const Offset(7.0, 3.0)));
    expect(firstBox.size.width, equals(800.0 - 12.0));
  });

  testWidgets('ListView underflow extents', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          addAutomaticKeepAlives: false,
          addSemanticIndexes: false,
          children: <Widget>[
            Container(height: 100.0),
            Container(height: 100.0),
            Container(height: 100.0),
          ],
        ),
      ),
    );

    final RenderSliverList list = tester.renderObject(find.byType(SliverList));

    expect(list.indexOf(list.firstChild), equals(0));
    expect(list.indexOf(list.lastChild), equals(2));
    expect(list.childScrollOffset(list.firstChild), equals(0.0));
    expect(list.geometry.scrollExtent, equals(300.0));

    expect(list, hasAGoodToStringDeep);
    expect(
      list.toStringDeep(minLevel: DiagnosticLevel.info),
      equalsIgnoringHashCodes(
        'RenderSliverList#00000 relayoutBoundary=up1\n'
        ' │ needs compositing\n'
        ' │ parentData: paintOffset=Offset(0.0, 0.0) (can use size)\n'
        ' │ constraints: SliverConstraints(AxisDirection.down,\n'
        ' │   GrowthDirection.forward, ScrollDirection.idle, scrollOffset:\n'
        ' │   0.0, remainingPaintExtent: 600.0, crossAxisExtent: 800.0,\n'
        ' │   crossAxisDirection: AxisDirection.right,\n'
        ' │   viewportMainAxisExtent: 600.0, remainingCacheExtent: 850.0,\n'
        ' │   cacheOrigin: 0.0)\n'
        ' │ geometry: SliverGeometry(scrollExtent: 300.0, paintExtent: 300.0,\n'
        ' │   maxPaintExtent: 300.0, cacheExtent: 300.0)\n'
        ' │ currently live children: 0 to 2\n'
        ' │\n'
        ' ├─child with index 0: RenderRepaintBoundary#00000 relayoutBoundary=up2\n'
        ' │ │ needs compositing\n'
        ' │ │ parentData: index=0; layoutOffset=0.0 (can use size)\n'
        ' │ │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        ' │ │ layer: OffsetLayer#00000\n'
        ' │ │ size: Size(800.0, 100.0)\n'
        ' │ │ metrics: 0.0% useful (1 bad vs 0 good)\n'
        ' │ │ diagnosis: insufficient data to draw conclusion (less than five\n'
        ' │ │   repaints)\n'
        ' │ │\n'
        ' │ └─child: RenderConstrainedBox#00000 relayoutBoundary=up3\n'
        ' │   │ parentData: <none> (can use size)\n'
        ' │   │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        ' │   │ size: Size(800.0, 100.0)\n'
        ' │   │ additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=100.0)\n'
        ' │   │\n'
        ' │   └─child: RenderLimitedBox#00000\n'
        ' │     │ parentData: <none> (can use size)\n'
        ' │     │ constraints: BoxConstraints(w=800.0, h=100.0)\n'
        ' │     │ size: Size(800.0, 100.0)\n'
        ' │     │ maxWidth: 0.0\n'
        ' │     │ maxHeight: 0.0\n'
        ' │     │\n'
        ' │     └─child: RenderConstrainedBox#00000\n'
        ' │         parentData: <none> (can use size)\n'
        ' │         constraints: BoxConstraints(w=800.0, h=100.0)\n'
        ' │         size: Size(800.0, 100.0)\n'
        ' │         additionalConstraints: BoxConstraints(biggest)\n'
        ' │\n'
        ' ├─child with index 1: RenderRepaintBoundary#00000 relayoutBoundary=up2\n'
        ' │ │ needs compositing\n'
        ' │ │ parentData: index=1; layoutOffset=100.0 (can use size)\n'
        ' │ │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        ' │ │ layer: OffsetLayer#00000\n'
        ' │ │ size: Size(800.0, 100.0)\n'
        ' │ │ metrics: 0.0% useful (1 bad vs 0 good)\n'
        ' │ │ diagnosis: insufficient data to draw conclusion (less than five\n'
        ' │ │   repaints)\n'
        ' │ │\n'
        ' │ └─child: RenderConstrainedBox#00000 relayoutBoundary=up3\n'
        ' │   │ parentData: <none> (can use size)\n'
        ' │   │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        ' │   │ size: Size(800.0, 100.0)\n'
        ' │   │ additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=100.0)\n'
        ' │   │\n'
        ' │   └─child: RenderLimitedBox#00000\n'
        ' │     │ parentData: <none> (can use size)\n'
        ' │     │ constraints: BoxConstraints(w=800.0, h=100.0)\n'
        ' │     │ size: Size(800.0, 100.0)\n'
        ' │     │ maxWidth: 0.0\n'
        ' │     │ maxHeight: 0.0\n'
        ' │     │\n'
        ' │     └─child: RenderConstrainedBox#00000\n'
        ' │         parentData: <none> (can use size)\n'
        ' │         constraints: BoxConstraints(w=800.0, h=100.0)\n'
        ' │         size: Size(800.0, 100.0)\n'
        ' │         additionalConstraints: BoxConstraints(biggest)\n'
        ' │\n'
        ' └─child with index 2: RenderRepaintBoundary#00000 relayoutBoundary=up2\n'
        '   │ needs compositing\n'
        '   │ parentData: index=2; layoutOffset=200.0 (can use size)\n'
        '   │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        '   │ layer: OffsetLayer#00000\n'
        '   │ size: Size(800.0, 100.0)\n'
        '   │ metrics: 0.0% useful (1 bad vs 0 good)\n'
        '   │ diagnosis: insufficient data to draw conclusion (less than five\n'
        '   │   repaints)\n'
        '   │\n'
        '   └─child: RenderConstrainedBox#00000 relayoutBoundary=up3\n'
        '     │ parentData: <none> (can use size)\n'
        '     │ constraints: BoxConstraints(w=800.0, 0.0<=h<=Infinity)\n'
        '     │ size: Size(800.0, 100.0)\n'
        '     │ additionalConstraints: BoxConstraints(0.0<=w<=Infinity, h=100.0)\n'
        '     │\n'
        '     └─child: RenderLimitedBox#00000\n'
        '       │ parentData: <none> (can use size)\n'
        '       │ constraints: BoxConstraints(w=800.0, h=100.0)\n'
        '       │ size: Size(800.0, 100.0)\n'
        '       │ maxWidth: 0.0\n'
        '       │ maxHeight: 0.0\n'
        '       │\n'
        '       └─child: RenderConstrainedBox#00000\n'
        '           parentData: <none> (can use size)\n'
        '           constraints: BoxConstraints(w=800.0, h=100.0)\n'
        '           size: Size(800.0, 100.0)\n'
        '           additionalConstraints: BoxConstraints(biggest)\n'
      ),
    );

    final ScrollPosition position = tester.state<ScrollableState>(find.byType(Scrollable)).position;

    expect(position.viewportDimension, equals(600.0));
    expect(position.minScrollExtent, equals(0.0));
  });

  testWidgets('ListView should not paint hidden children', (WidgetTester tester) async {
    const Text text = Text('test');
    await tester.pumpWidget(
        Directionality(
            textDirection: TextDirection.ltr,
            child: Center(
              child: Container(
                  height: 200.0,
                  child: ListView(
                    cacheExtent: 500.0,
                    controller: ScrollController(initialScrollOffset: 300.0),
                    children: <Widget>[
                      Container(height: 140.0, child: text),
                      Container(height: 160.0, child: text),
                      Container(height: 90.0, child: text),
                      Container(height: 110.0, child: text),
                      Container(height: 80.0, child: text),
                      Container(height: 70.0, child: text),
                    ],
                  ),
              ),
            ),
        ),
    );

    final RenderSliverList list = tester.renderObject(find.byType(SliverList));
    expect(list, paintsExactlyCountTimes(#drawParagraph, 2));
  });

  testWidgets('ListView should paint with offset', (WidgetTester tester) async {
    await tester.pumpWidget(
        MaterialApp(
            home: Scaffold(
                body: Container(
                    height: 500.0,
                    child: CustomScrollView(
                      controller: ScrollController(initialScrollOffset: 120.0),
                      slivers: <Widget>[
                        const SliverAppBar(
                          expandedHeight: 250.0,
                        ),
                        SliverList(
                            delegate: ListView.builder(
                                itemExtent: 100.0,
                                itemCount: 100,
                                itemBuilder: (_, __) => Container(
                                  height: 40.0,
                                  child: const Text('hey'),
                                )).childrenDelegate),
                      ],
                    ),
                ),
            ),
        ),
    );

    final RenderObject renderObject = tester.renderObject(find.byType(Scrollable));
    expect(renderObject, paintsExactlyCountTimes(#drawParagraph, 10));
  });

  testWidgets('ListView should paint with rtl', (WidgetTester tester) async {
    await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.rtl,
          child: Container(
            height: 200.0,
            child: ListView.builder(
              padding: const EdgeInsets.symmetric(
                  horizontal: 0.0, vertical: 0.0),
              scrollDirection: Axis.horizontal,
              itemExtent: 200.0,
              itemCount: 10,
              itemBuilder: (_, int i) => Container(
                height: 200.0,
                width: 200.0,
                color: i % 2 == 0 ? Colors.black : Colors.red,
              ),
            ),
          ),
        ),
    );

    final RenderObject renderObject = tester.renderObject(find.byType(Scrollable));
    expect(renderObject, paintsExactlyCountTimes(#drawRect, 4));
  });
}
