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

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart';

import 'states.dart';

void main() {
  testWidgets('ListView control test', (WidgetTester tester) async {
    final List<String> log = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: kStates.map<Widget>((String state) {
            return GestureDetector(
              onTap: () {
                log.add(state);
              },
              child: Container(
                height: 200.0,
                color: const Color(0xFF0000FF),
                child: Text(state),
              ),
              dragStartBehavior: DragStartBehavior.down,
            );
          }).toList(),
        ),
      ),
    );

    await tester.tap(find.text('Alabama'));
    expect(log, equals(<String>['Alabama']));
    log.clear();

    expect(find.text('Nevada'), findsNothing);

    await tester.drag(find.text('Alabama'), const Offset(0.0, -4000.0));
    await tester.pump();

    expect(find.text('Alabama'), findsNothing);
    expect(tester.getCenter(find.text('Massachusetts')), equals(const Offset(400.0, 100.0)));

    await tester.tap(find.text('Massachusetts'));
    expect(log, equals(<String>['Massachusetts']));
    log.clear();
  });

  testWidgets('ListView restart ballistic activity out of range', (WidgetTester tester) async {
    Widget buildListView(int n) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          dragStartBehavior: DragStartBehavior.down,
          children: kStates.take(n).map<Widget>((String state) {
            return Container(
              height: 200.0,
              color: const Color(0xFF0000FF),
              child: Text(state),
            );
          }).toList(),
        ),
      );
    }

    await tester.pumpWidget(buildListView(30));
    await tester.fling(find.byType(ListView), const Offset(0.0, -4000.0), 4000.0);
    await tester.pumpWidget(buildListView(15));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pumpAndSettle(const Duration(milliseconds: 100));

    final Viewport viewport = tester.widget(find.byType(Viewport));
    expect(viewport.offset.pixels, equals(2400.0));
  });

  testWidgets('CustomScrollView control test', (WidgetTester tester) async {
    final List<String> log = <String>[];

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: CustomScrollView(
          dragStartBehavior: DragStartBehavior.down,
          slivers: <Widget>[
            SliverList(
              delegate: SliverChildListDelegate(
                kStates.map<Widget>((String state) {
                  return GestureDetector(
                    dragStartBehavior: DragStartBehavior.down,
                    onTap: () {
                      log.add(state);
                    },
                    child: Container(
                      height: 200.0,
                      color: const Color(0xFF0000FF),
                      child: Text(state),
                    ),
                  );
                }).toList(),
              ),
            ),
          ],
        ),
      ),
    );

    await tester.tap(find.text('Alabama'));
    expect(log, equals(<String>['Alabama']));
    log.clear();

    expect(find.text('Nevada'), findsNothing);

    await tester.drag(find.text('Alabama'), const Offset(0.0, -4000.0));
    await tester.pump();

    expect(find.text('Alabama'), findsNothing);
    expect(tester.getCenter(find.text('Massachusetts')), equals(const Offset(400.0, 100.0)));

    await tester.tap(find.text('Massachusetts'));
    expect(log, equals(<String>['Massachusetts']));
    log.clear();
  });

  testWidgets('Can jumpTo during drag', (WidgetTester tester) async {
    final List<Type> log = <Type>[];
    final ScrollController controller = ScrollController();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: NotificationListener<ScrollNotification>(
          onNotification: (ScrollNotification notification) {
            log.add(notification.runtimeType);
            return false;
          },
          child: ListView(
            controller: controller,
            children: kStates.map<Widget>((String state) {
              return Container(
                height: 200.0,
                child: Text(state),
              );
            }).toList(),
          ),
        ),
      ),
    );

    expect(log, isEmpty);

    final TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0));
    await gesture.moveBy(const Offset(0.0, -100.0));

    expect(log, equals(<Type>[
      ScrollStartNotification,
      UserScrollNotification,
      ScrollUpdateNotification,
    ]));
    log.clear();

    await tester.pump();

    controller.jumpTo(550.0);

    expect(controller.offset, equals(550.0));
    expect(log, equals(<Type>[
      ScrollEndNotification,
      UserScrollNotification,
      ScrollStartNotification,
      ScrollUpdateNotification,
      ScrollEndNotification,
    ]));
    log.clear();

    await tester.pump();
    await gesture.moveBy(const Offset(0.0, -100.0));

    expect(controller.offset, equals(550.0));
    expect(log, isEmpty);
  });

  testWidgets('Vertical CustomScrollViews are primary by default', (WidgetTester tester) async {
    const CustomScrollView view = CustomScrollView(scrollDirection: Axis.vertical);
    expect(view.primary, isTrue);
  });

  testWidgets('Vertical ListViews are primary by default', (WidgetTester tester) async {
    final ListView view = ListView(scrollDirection: Axis.vertical);
    expect(view.primary, isTrue);
  });

  testWidgets('Vertical GridViews are primary by default', (WidgetTester tester) async {
    final GridView view = GridView.count(
      scrollDirection: Axis.vertical,
      crossAxisCount: 1,
    );
    expect(view.primary, isTrue);
  });

  testWidgets('Horizontal CustomScrollViews are non-primary by default', (WidgetTester tester) async {
    const CustomScrollView view = CustomScrollView(scrollDirection: Axis.horizontal);
    expect(view.primary, isFalse);
  });

  testWidgets('Horizontal ListViews are non-primary by default', (WidgetTester tester) async {
    final ListView view = ListView(scrollDirection: Axis.horizontal);
    expect(view.primary, isFalse);
  });

  testWidgets('Horizontal GridViews are non-primary by default', (WidgetTester tester) async {
    final GridView view = GridView.count(
      scrollDirection: Axis.horizontal,
      crossAxisCount: 1,
    );
    expect(view.primary, isFalse);
  });

  testWidgets('CustomScrollViews with controllers are non-primary by default', (WidgetTester tester) async {
    final CustomScrollView view = CustomScrollView(
      controller: ScrollController(),
      scrollDirection: Axis.vertical,
    );
    expect(view.primary, isFalse);
  });

  testWidgets('ListViews with controllers are non-primary by default', (WidgetTester tester) async {
    final ListView view = ListView(
      controller: ScrollController(),
      scrollDirection: Axis.vertical,
    );
    expect(view.primary, isFalse);
  });

  testWidgets('GridViews with controllers are non-primary by default', (WidgetTester tester) async {
    final GridView view = GridView.count(
      controller: ScrollController(),
      scrollDirection: Axis.vertical,
      crossAxisCount: 1,
    );
    expect(view.primary, isFalse);
  });

  testWidgets('CustomScrollView sets PrimaryScrollController when primary', (WidgetTester tester) async {
    final ScrollController primaryScrollController = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: PrimaryScrollController(
          controller: primaryScrollController,
          child: const CustomScrollView(primary: true),
        ),
      ),
    );
    final Scrollable scrollable = tester.widget(find.byType(Scrollable));
    expect(scrollable.controller, primaryScrollController);
  });

  testWidgets('ListView sets PrimaryScrollController when primary', (WidgetTester tester) async {
    final ScrollController primaryScrollController = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: PrimaryScrollController(
          controller: primaryScrollController,
          child: ListView(primary: true),
        ),
      ),
    );
    final Scrollable scrollable = tester.widget(find.byType(Scrollable));
    expect(scrollable.controller, primaryScrollController);
  });

  testWidgets('GridView sets PrimaryScrollController when primary', (WidgetTester tester) async {
    final ScrollController primaryScrollController = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: PrimaryScrollController(
          controller: primaryScrollController,
          child: GridView.count(primary: true, crossAxisCount: 1),
        ),
      ),
    );
    final Scrollable scrollable = tester.widget(find.byType(Scrollable));
    expect(scrollable.controller, primaryScrollController);
  });

  testWidgets('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async {
    const Key innerKey = Key('inner');
    final ScrollController primaryScrollController = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: PrimaryScrollController(
          controller: primaryScrollController,
          child: ListView(
            primary: true,
            children: <Widget>[
              Container(
                constraints: const BoxConstraints(maxHeight: 200.0),
                child: ListView(key: innerKey, primary: true),
              ),
            ],
          ),
        ),
      ),
    );

    final Scrollable innerScrollable = tester.widget(
      find.descendant(
        of: find.byKey(innerKey),
        matching: find.byType(Scrollable),
      ),
    );
    expect(innerScrollable.controller, isNull);
  });

  testWidgets('Primary ListViews are always scrollable', (WidgetTester tester) async {
    final ListView view = ListView(primary: true);
    expect(view.physics, isInstanceOf<AlwaysScrollableScrollPhysics>());
  });

  testWidgets('Non-primary ListViews are not always scrollable', (WidgetTester tester) async {
    final ListView view = ListView(primary: false);
    expect(view.physics, isNot(isInstanceOf<AlwaysScrollableScrollPhysics>()));
  });

  testWidgets('Defaulting-to-primary ListViews are always scrollable', (WidgetTester tester) async {
    final ListView view = ListView(scrollDirection: Axis.vertical);
    expect(view.physics, isInstanceOf<AlwaysScrollableScrollPhysics>());
  });

  testWidgets('Defaulting-to-not-primary ListViews are not always scrollable', (WidgetTester tester) async {
    final ListView view = ListView(scrollDirection: Axis.horizontal);
    expect(view.physics, isNot(isInstanceOf<AlwaysScrollableScrollPhysics>()));
  });

  testWidgets('primary:true leads to scrolling', (WidgetTester tester) async {
    bool scrolled = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: NotificationListener<OverscrollNotification>(
          onNotification: (OverscrollNotification message) { scrolled = true; return false; },
          child: ListView(
            primary: true,
            children: const <Widget>[],
          ),
        ),
      ),
    );
    await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 100.0));
    expect(scrolled, isTrue);
  });

  testWidgets('primary:false leads to no scrolling', (WidgetTester tester) async {
    bool scrolled = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: NotificationListener<OverscrollNotification>(
          onNotification: (OverscrollNotification message) { scrolled = true; return false; },
          child: ListView(
            primary: false,
            children: const <Widget>[],
          ),
        ),
      ),
    );
    await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 100.0));
    expect(scrolled, isFalse);
  });

  testWidgets('physics:AlwaysScrollableScrollPhysics actually overrides primary:false default behavior', (WidgetTester tester) async {
    bool scrolled = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: NotificationListener<OverscrollNotification>(
          onNotification: (OverscrollNotification message) { scrolled = true; return false; },
          child: ListView(
            primary: false,
            physics: const AlwaysScrollableScrollPhysics(),
            children: const <Widget>[],
          ),
        ),
      ),
    );
    await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 100.0));
    expect(scrolled, isTrue);
  });

  testWidgets('physics:ScrollPhysics actually overrides primary:true default behavior', (WidgetTester tester) async {
    bool scrolled = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: NotificationListener<OverscrollNotification>(
          onNotification: (OverscrollNotification message) { scrolled = true; return false; },
          child: ListView(
            primary: true,
            physics: const ScrollPhysics(),
            children: const <Widget>[],
          ),
        ),
      ),
    );
    await tester.dragFrom(const Offset(100.0, 100.0), const Offset(0.0, 100.0));
    expect(scrolled, isFalse);
  });

  testWidgets('separatorBuilder must return something', (WidgetTester tester) async {
    const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];

    Widget buildFrame(Widget firstSeparator) {
      return MaterialApp(
        home: Material(
          child: ListView.separated(
            itemBuilder: (BuildContext context, int index) {
              return Text(listOfValues[index]);
            },
            separatorBuilder: (BuildContext context, int index) {
              if (index == 0) {
                return firstSeparator;
              } else {
                return const Divider();
              }
            },
            itemCount: listOfValues.length,
          ),
        ),
      );
    }

    // A separatorBuilder that always returns a Divider is fine
    await tester.pumpWidget(buildFrame(const Divider()));
    expect(tester.takeException(), isNull);

    // A separatorBuilder that returns null throws a FlutterError
    await tester.pumpWidget(buildFrame(null));
    expect(tester.takeException(), isInstanceOf<FlutterError>());
    expect(find.byType(ErrorWidget), findsOneWidget);
  });

  testWidgets('itemBuilder can return null', (WidgetTester tester) async {
    const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];
    const Key key = Key('list');
    const int RENDER_NULL_AT = 2; // only render the first 2 values

    Widget buildFrame() {
      return MaterialApp(
        home: Material(
          child: ListView.builder(
            key: key,
            itemBuilder: (BuildContext context, int index) {
              if (index == RENDER_NULL_AT) {
                return null;
              }
              return Text(listOfValues[index]);
            },
            itemCount: listOfValues.length,
          ),
        ),
      );
    }

    // The length of a list is itemCount or the index of the first itemBuilder
    // that returns null, whichever is smaller
    await tester.pumpWidget(buildFrame());
    expect(tester.takeException(), isNull);
    expect(find.byType(ErrorWidget), findsNothing);
    expect(find.byType(Text), findsNWidgets(RENDER_NULL_AT));
  });

  testWidgets('when itemBuilder throws, creates Error Widget', (WidgetTester tester) async {
    const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];

    Widget buildFrame(bool throwOnFirstItem) {
      return MaterialApp(
        home: Material(
          child: ListView.builder(
            itemBuilder: (BuildContext context, int index) {
              if (index == 0 && throwOnFirstItem) {
                throw Exception('itemBuilder fail');
              }
              return Text(listOfValues[index]);
            },
            itemCount: listOfValues.length,
          ),
        ),
      );
    }

    // When itemBuilder doesn't throw, no ErrorWidget
    await tester.pumpWidget(buildFrame(false));
    expect(tester.takeException(), isNull);
    final Finder finder = find.byType(ErrorWidget);
    expect(find.byType(ErrorWidget), findsNothing);

    // When it does throw, one error widget is rendered in the item's place
    await tester.pumpWidget(buildFrame(true));
    expect(tester.takeException(), isInstanceOf<Exception>());
    expect(finder, findsOneWidget);
  });

  testWidgets('when separatorBuilder throws, creates ErrorWidget', (WidgetTester tester) async {
    const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];
    const Key key = Key('list');

    Widget buildFrame(bool throwOnFirstSeparator) {
      return MaterialApp(
        home: Material(
          child: ListView.separated(
            key: key,
            itemBuilder: (BuildContext context, int index) {
              return Text(listOfValues[index]);
            },
            separatorBuilder: (BuildContext context, int index) {
              if (index == 0 && throwOnFirstSeparator) {
                throw Exception('separatorBuilder fail');
              }
              return const Divider();
            },
            itemCount: listOfValues.length,
          ),
        ),
      );
    }

    // When separatorBuilder doesn't throw, no ErrorWidget
    await tester.pumpWidget(buildFrame(false));
    expect(tester.takeException(), isNull);
    final Finder finder = find.byType(ErrorWidget);
    expect(find.byType(ErrorWidget), findsNothing);

    // When it does throw, one error widget is rendered in the separator's place
    await tester.pumpWidget(buildFrame(true));
    expect(tester.takeException(), isInstanceOf<Exception>());
    expect(finder, findsOneWidget);
  });
}
