// 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 'dart:ui' as ui show Image;

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

import '../painting/image_test_utils.dart';

void main() {

  late ui.Image testImage;

  setUpAll(() async {
    testImage = await createTestImage(width: 10, height: 10);
  });

  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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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 someone 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.loadBuffer(testImageProvider, PaintingBinding.instance.instantiateImageCodecFromBuffer));
    // 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!);
    final TestImageProvider testImageProvider = TestImageProvider(testImage.clone());
    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(testImage.clone());
    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.loadBuffer(testImageProvider, PaintingBinding.instance.instantiateImageCodecFromBuffer));

    // Verify that this hasn't changed 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({ super.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({ super.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;
  }
}
