// 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 '../painting/image_test_utils.dart';
import '../painting/mocks_for_image_cache.dart' show TestImage;

void main() {
  tearDown(() {
    imageCache.clear();
  });

  T _findPhysics<T extends ScrollPhysics>(WidgetTester tester) {
    return Scrollable.of(find.byType(TestWidget).evaluate().first).position.physics as T;
  }

  ScrollMetrics _findMetrics(WidgetTester tester) {
    return Scrollable.of(find.byType(TestWidget).evaluate().first).position;
  }

  testWidgets('ScrollAwareImageProvider does not delay if widget is not in scrollable', (WidgetTester tester) async {
    final GlobalKey<TestWidgetState> key = GlobalKey<TestWidgetState>();
    await tester.pumpWidget(TestWidget(key));

    final DisposableBuildContext context = DisposableBuildContext(key.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);

    expect(testImageProvider.configuration, ImageConfiguration.empty);
    expect(stream.completer, isNotNull);
    expect(stream.completer.hasListeners, true);
    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.currentSize, 0);

    testImageProvider.complete();

    expect(imageCache.currentSize, 1);
  });

  testWidgets('ScrollAwareImageProvider does not delay if in scrollable that is not scrolling', (WidgetTester tester) async {
    final GlobalKey<TestWidgetState> key = GlobalKey<TestWidgetState>();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: ListView(
        physics: RecordingPhysics(),
        children: <Widget>[
          TestWidget(key),
        ],
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(key.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);

    expect(testImageProvider.configuration, ImageConfiguration.empty);
    expect(stream.completer, isNotNull);
    expect(stream.completer.hasListeners, true);
    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.currentSize, 0);

    testImageProvider.complete();

    expect(imageCache.currentSize, 1);
    expect(_findPhysics<RecordingPhysics>(tester).velocities, <double>[0]);
  });

  testWidgets('ScrollAwareImageProvider does not delay if in scrollable that is scrolling slowly', (WidgetTester tester) async {
    final List<GlobalKey<TestWidgetState>> keys = <GlobalKey<TestWidgetState>>[];
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: ListView.builder(
        physics: RecordingPhysics(),
        controller: scrollController,
        itemBuilder: (BuildContext context, int index) {
          keys.add(GlobalKey<TestWidgetState>());
          return TestWidget(keys.last);
        },
        itemCount: 50,
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    scrollController.animateTo(
      100,
      duration: const Duration(seconds: 2),
      curve: Curves.fastLinearToSlowEaseIn,
    );
    await tester.pump();
    final RecordingPhysics physics = _findPhysics<RecordingPhysics>(tester);

    expect(physics.velocities.length, 0);
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    expect(physics.velocities.length, 1);
    expect(
      const ScrollPhysics().recommendDeferredLoading(
        physics.velocities.first,
        _findMetrics(tester),
        find.byType(TestWidget).evaluate().first,
      ),
      false,
    );

    expect(testImageProvider.configuration, ImageConfiguration.empty);
    expect(stream.completer, isNotNull);
    expect(stream.completer.hasListeners, true);
    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.currentSize, 0);

    testImageProvider.complete();

    expect(imageCache.currentSize, 1);
  });

  testWidgets('ScrollAwareImageProvider delays if in scrollable that is scrolling fast', (WidgetTester tester) async {
    final List<GlobalKey<TestWidgetState>> keys = <GlobalKey<TestWidgetState>>[];
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: ListView.builder(
        physics: RecordingPhysics(),
        controller: scrollController,
        itemBuilder: (BuildContext context, int index) {
          keys.add(GlobalKey<TestWidgetState>());
          return TestWidget(keys.last);
        },
        itemCount: 50,
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    scrollController.animateTo(
      3000,
      duration: const Duration(seconds: 2),
      curve: Curves.fastLinearToSlowEaseIn,
    );
    await tester.pump();
    final RecordingPhysics physics = _findPhysics<RecordingPhysics>(tester);

    expect(physics.velocities.length, 0);
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    expect(physics.velocities.length, 1);
    expect(
      const ScrollPhysics().recommendDeferredLoading(
        physics.velocities.first,
        _findMetrics(tester),
        find.byType(TestWidget).evaluate().first,
      ),
      true,
    );

    expect(testImageProvider.configuration, null);
    expect(stream.completer, null);

    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.currentSize, 0);

    await tester.pump(const Duration(seconds: 1));
    expect(physics.velocities.last, 0);

    expect(testImageProvider.configuration, ImageConfiguration.empty);
    expect(stream.completer, isNotNull);
    expect(stream.completer.hasListeners, true);

    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.currentSize, 0);

    testImageProvider.complete();

    expect(imageCache.currentSize, 1);
  });

  testWidgets('ScrollAwareImageProvider delays if in scrollable that is scrolling fast and fizzles if disposed', (WidgetTester tester) async {
    final List<GlobalKey<TestWidgetState>> keys = <GlobalKey<TestWidgetState>>[];
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: ListView.builder(
        physics: RecordingPhysics(),
        controller: scrollController,
        itemBuilder: (BuildContext context, int index) {
          keys.add(GlobalKey<TestWidgetState>());
          return TestWidget(keys.last);
        },
        itemCount: 50,
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    scrollController.animateTo(
      3000,
      duration: const Duration(seconds: 2),
      curve: Curves.fastLinearToSlowEaseIn,
    );
    await tester.pump();
    final RecordingPhysics physics = _findPhysics<RecordingPhysics>(tester);

    expect(physics.velocities.length, 0);
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    expect(physics.velocities.length, 1);
    expect(
      const ScrollPhysics().recommendDeferredLoading(
        physics.velocities.first,
        _findMetrics(tester),
        find.byType(TestWidget).evaluate().first,
      ),
      true,
    );

    expect(testImageProvider.configuration, null);
    expect(stream.completer, null);

    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.currentSize, 0);

    // as if we had picked a context that scrolled out of the tree.
    context.dispose();

    await tester.pump(const Duration(seconds: 1));
    expect(physics.velocities.length, 1);

    expect(testImageProvider.configuration, null);
    expect(stream.completer, null);

    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.currentSize, 0);

    testImageProvider.complete();

    expect(imageCache.currentSize, 0);
  });

  testWidgets('ScrollAwareImageProvider resolves from ImageCache and does not set completer twice', (WidgetTester tester) async {
    final GlobalKey<TestWidgetState> key = GlobalKey<TestWidgetState>();
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: SingleChildScrollView(
        physics: ControllablePhysics(),
        controller: scrollController,
        child: TestWidget(key),
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(key.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    final ControllablePhysics physics = _findPhysics<ControllablePhysics>(tester);
    physics.recommendDeferredLoadingValue = true;

    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);

    expect(testImageProvider.configuration, null);
    expect(stream.completer, null);
    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.currentSize, 0);

    // Simulate a case where somone else has managed to complete this stream -
    // so it can land in the cache right before we stop scrolling fast.
    // If we miss the early return, we will fail.
    testImageProvider.complete();

    imageCache.putIfAbsent(testImageProvider, () => testImageProvider.load(testImageProvider, PaintingBinding.instance.instantiateImageCodec));
    // We've stopped scrolling fast.
    physics.recommendDeferredLoadingValue = false;
    await tester.idle();

    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.currentSize, 1);
    expect(testImageProvider.loadCallCount, 1);
    expect(stream.completer, null);
  });

  testWidgets('ScrollAwareImageProvider does not block LRU updates to image cache', (WidgetTester tester) async {
    final int oldSize = imageCache.maximumSize;
    imageCache.maximumSize = 1;

    final GlobalKey<TestWidgetState> key = GlobalKey<TestWidgetState>();
    final ScrollController scrollController = ScrollController();
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: SingleChildScrollView(
        physics: ControllablePhysics(),
        controller: scrollController,
        child: TestWidget(key),
      ),
    ));

    final DisposableBuildContext context = DisposableBuildContext(key.currentState);
    const TestImage testImage = TestImage(width: 10, height: 10);
    final TestImageProvider testImageProvider = TestImageProvider(testImage);
    final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
      context: context,
      imageProvider: testImageProvider,
    );

    expect(testImageProvider.configuration, null);
    expect(imageCache.containsKey(testImageProvider), false);

    final ControllablePhysics physics = _findPhysics<ControllablePhysics>(tester);
    physics.recommendDeferredLoadingValue = true;

    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);

    expect(testImageProvider.configuration, null);
    expect(stream.completer, null);
    expect(imageCache.currentSize, 0);

    // Occupy the only slot in the cache with another image.
    final TestImageProvider testImageProvider2 = TestImageProvider(const TestImage());
    testImageProvider2.complete();
    await precacheImage(testImageProvider2, context.context);
    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.containsKey(testImageProvider2), true);
    expect(imageCache.currentSize, 1);

    // Complete the original image while we're still scrolling fast.
    testImageProvider.complete();
    stream.setCompleter(testImageProvider.load(testImageProvider, PaintingBinding.instance.instantiateImageCodec));

    // Verify that this hasn't chagned the cache state yet
    expect(imageCache.containsKey(testImageProvider), false);
    expect(imageCache.containsKey(testImageProvider2), true);
    expect(imageCache.currentSize, 1);
    expect(testImageProvider.loadCallCount, 1);

    await tester.pump();

    // After pumping a frame, the original image should be in the cache because
    // it took the LRU slot.
    expect(imageCache.containsKey(testImageProvider), true);
    expect(imageCache.containsKey(testImageProvider2), false);
    expect(imageCache.currentSize, 1);
    expect(testImageProvider.loadCallCount, 1);

    imageCache.maximumSize = oldSize;
  });
}

class TestWidget extends StatefulWidget {
  const TestWidget(Key key) : super(key: key);

  @override
  State<TestWidget> createState() => TestWidgetState();
}

class TestWidgetState extends State<TestWidget> {
  @override
  Widget build(BuildContext context) => const SizedBox(height: 50);
}

class RecordingPhysics extends ScrollPhysics {
  RecordingPhysics({ ScrollPhysics parent }) : super(parent: parent);

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

  @override
  RecordingPhysics applyTo(ScrollPhysics ancestor) {
    return RecordingPhysics(parent: buildParent(ancestor));
  }

  @override
  bool recommendDeferredLoading(double velocity, ScrollMetrics metrics, BuildContext context) {
    velocities.add(velocity);
    return super.recommendDeferredLoading(velocity, metrics, context);
  }
}

// Ignore this so that we can mutate whether we defer loading or not at specific
// times without worrying about actual scrolling mechanics.
// ignore: must_be_immutable
class ControllablePhysics extends ScrollPhysics {
  ControllablePhysics({ ScrollPhysics parent }) : super(parent: parent);

  bool recommendDeferredLoadingValue = false;

  @override
  ControllablePhysics applyTo(ScrollPhysics ancestor) {
    return ControllablePhysics(parent: buildParent(ancestor));
  }

  @override
  bool recommendDeferredLoading(double velocity, ScrollMetrics metrics, BuildContext context) {
    return recommendDeferredLoadingValue;
  }
}
