// 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/widgets.dart';

import 'states.dart';

void main() {
  testWidgets('ScrollController control test', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();

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

    double realOffset() {
      return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
    }

    expect(controller.offset, equals(0.0));
    expect(realOffset(), equals(controller.offset));

    controller.jumpTo(653.0);

    expect(controller.offset, equals(653.0));
    expect(realOffset(), equals(controller.offset));

    await tester.pump();

    expect(controller.offset, equals(653.0));
    expect(realOffset(), equals(controller.offset));

    controller.animateTo(326.0, duration: const Duration(milliseconds: 300), curve: Curves.ease);
    await tester.pumpAndSettle(const Duration(milliseconds: 100));

    expect(controller.offset, equals(326.0));
    expect(realOffset(), equals(controller.offset));

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          key: const Key('second'),
          controller: controller,
          children: kStates.map<Widget>((String state) {
            return Container(
              height: 200.0,
              child: Text(state),
            );
          }).toList(),
        ),
      ),
    );

    expect(controller.offset, equals(0.0));
    expect(realOffset(), equals(controller.offset));

    controller.jumpTo(653.0);

    expect(controller.offset, equals(653.0));
    expect(realOffset(), equals(controller.offset));

    final ScrollController controller2 = ScrollController();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          key: const Key('second'),
          controller: controller2,
          children: kStates.map<Widget>((String state) {
            return Container(
              height: 200.0,
              child: Text(state),
            );
          }).toList(),
        ),
      ),
    );

    expect(() => controller.offset, throwsAssertionError);
    expect(controller2.offset, equals(653.0));
    expect(realOffset(), equals(controller2.offset));

    expect(() => controller.jumpTo(120.0), throwsAssertionError);
    expect(() => controller.animateTo(132.0, duration: const Duration(milliseconds: 300), curve: Curves.ease), throwsAssertionError);

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          key: const Key('second'),
          controller: controller2,
          physics: const BouncingScrollPhysics(),
          children: kStates.map<Widget>((String state) {
            return Container(
              height: 200.0,
              child: Text(state),
            );
          }).toList(),
        ),
      ),
    );

    expect(controller2.offset, equals(653.0));
    expect(realOffset(), equals(controller2.offset));

    controller2.jumpTo(432.0);

    expect(controller2.offset, equals(432.0));
    expect(realOffset(), equals(controller2.offset));

    await tester.pump();

    expect(controller2.offset, equals(432.0));
    expect(realOffset(), equals(controller2.offset));
  });

  testWidgets('ScrollController control test', (WidgetTester tester) async {
    final ScrollController controller = ScrollController(
      initialScrollOffset: 209.0,
    );

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.count(
          crossAxisCount: 4,
          controller: controller,
          children: kStates.map<Widget>((String state) => Text(state)).toList(),
        ),
      ),
    );

    double realOffset() {
      return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
    }

    expect(controller.offset, equals(209.0));
    expect(realOffset(), equals(controller.offset));

    controller.jumpTo(105.0);

    await tester.pump();

    expect(controller.offset, equals(105.0));
    expect(realOffset(), equals(controller.offset));

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: GridView.count(
          crossAxisCount: 2,
          controller: controller,
          children: kStates.map<Widget>((String state) => Text(state)).toList(),
        ),
      ),
    );

    expect(controller.offset, equals(105.0));
    expect(realOffset(), equals(controller.offset));
  });

  testWidgets('DrivenScrollActivity ending after dispose', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          controller: controller,
          children: <Widget>[ Container(height: 200000.0) ],
        ),
      ),
    );

    controller.animateTo(1000.0, duration: const Duration(seconds: 1), curve: Curves.linear);

    await tester.pump(); // Start the animation.

    // We will now change the tree on the same frame as the animation ends.
    await tester.pumpWidget(Container(), const Duration(seconds: 2));
  });

  testWidgets('Read operations on ScrollControllers with no positions fail', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    expect(() => controller.offset, throwsAssertionError);
    expect(() => controller.position, throwsAssertionError);
  });

  testWidgets('Read operations on ScrollControllers with more than one position fail', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          children: <Widget>[
            Container(
              constraints: const BoxConstraints(maxHeight: 500.0),
              child: ListView(
                controller: controller,
                children: kStates.map<Widget>((String state) {
                  return Container(height: 200.0, child: Text(state));
                }).toList(),
              ),
            ),
            Container(
              constraints: const BoxConstraints(maxHeight: 500.0),
              child: ListView(
                controller: controller,
                children: kStates.map<Widget>((String state) {
                  return Container(height: 200.0, child: Text(state));
                }).toList(),
              ),
            ),
          ],
        ),
      ),
    );

    expect(() => controller.offset, throwsAssertionError);
    expect(() => controller.position, throwsAssertionError);
  });

  testWidgets('Write operations on ScrollControllers with no positions fail', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    expect(() => controller.animateTo(1.0, duration: const Duration(seconds: 1), curve: Curves.linear), throwsAssertionError);
    expect(() => controller.jumpTo(1.0), throwsAssertionError);
  });

  testWidgets('Write operations on ScrollControllers with more than one position do not throw', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: ListView(
          children: <Widget>[
            Container(
              constraints: const BoxConstraints(maxHeight: 500.0),
              child: ListView(
                controller: controller,
                children: kStates.map<Widget>((String state) {
                  return Container(height: 200.0, child: Text(state));
                }).toList(),
              ),
            ),
            Container(
              constraints: const BoxConstraints(maxHeight: 500.0),
              child: ListView(
                controller: controller,
                children: kStates.map<Widget>((String state) {
                  return Container(height: 200.0, child: Text(state));
                }).toList(),
              ),
            ),
          ],
        ),
      ),
    );

    controller.jumpTo(1.0);
    controller.animateTo(1.0, duration: const Duration(seconds: 1), curve: Curves.linear);
    await tester.pumpAndSettle();
  });

  testWidgets('Scroll controllers notify when the position changes', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();

    final List<double> log = <double>[];

    controller.addListener(() {
      log.add(controller.offset);
    });

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

    expect(log, isEmpty);

    await tester.drag(find.byType(ListView), const Offset(0.0, -250.0));

    expect(log, equals(<double>[ 20.0, 250.0 ]));
    log.clear();

    controller.dispose();

    await tester.drag(find.byType(ListView), const Offset(0.0, -130.0));
    expect(log, isEmpty);
  });

  testWidgets('keepScrollOffset', (WidgetTester tester) async {
    final PageStorageBucket bucket = PageStorageBucket();

    Widget buildFrame(ScrollController controller) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: PageStorage(
          bucket: bucket,
          child: KeyedSubtree(
            key: const PageStorageKey<String>('ListView'),
            child: ListView(
              key: UniqueKey(), // it's a different ListView every time
              controller: controller,
              children: List<Widget>.generate(50, (int index) {
                return Container(height: 100.0, child: Text('Item $index'));
              }).toList(),
            ),
          ),
        ),
      );
    }

    // keepScrollOffset: true (the default). The scroll offset is restored
    // when the ListView is recreated with a new ScrollController.

    // The initialScrollOffset is used in this case, because there's no saved
    // scroll offset.
    ScrollController controller = ScrollController(initialScrollOffset: 200.0);
    await tester.pumpWidget(buildFrame(controller));
    expect(tester.getTopLeft(find.widgetWithText(Container, 'Item 2')), Offset.zero);

    controller.jumpTo(2000.0);
    await tester.pump();
    expect(tester.getTopLeft(find.widgetWithText(Container, 'Item 20')), Offset.zero);

    // The initialScrollOffset isn't used in this case, because the scrolloffset
    // can be restored.
    controller = ScrollController(initialScrollOffset: 25.0);
    await tester.pumpWidget(buildFrame(controller));
    expect(controller.offset, 2000.0);
    expect(tester.getTopLeft(find.widgetWithText(Container, 'Item 20')), Offset.zero);

    // keepScrollOffset: false. The scroll offset is -not- restored
    // when the ListView is recreated with a new ScrollController and
    // the initialScrollOffset is used.

    controller = ScrollController(keepScrollOffset: false, initialScrollOffset: 100.0);
    await tester.pumpWidget(buildFrame(controller));
    expect(controller.offset, 100.0);
    expect(tester.getTopLeft(find.widgetWithText(Container, 'Item 1')), Offset.zero);

  });
}
