// 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:async';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

import '../image_data.dart';
import '../rendering/rendering_tester.dart';
import 'mocks_for_image_cache.dart';

void main() {
  TestRenderingFlutterBinding();

  Future<ui.Codec> _basicDecoder(Uint8List bytes, {int? cacheWidth, int? cacheHeight, bool? allowUpscaling}) {
    return PaintingBinding.instance!.instantiateImageCodec(bytes, cacheWidth: cacheWidth, cacheHeight: cacheHeight, allowUpscaling: allowUpscaling ?? false);
  }

  FlutterExceptionHandler? oldError;
  setUp(() {
    oldError = FlutterError.onError;
  });

  tearDown(() {
    FlutterError.onError = oldError;
    PaintingBinding.instance!.imageCache!.clear();
    PaintingBinding.instance!.imageCache!.clearLiveImages();
  });

  tearDown(() {
    imageCache!.clear();
  });

  test('AssetImageProvider - evicts on failure to load', () async {
    final Completer<FlutterError> error = Completer<FlutterError>();
    FlutterError.onError = (FlutterErrorDetails details) {
      error.complete(details.exception as FlutterError);
    };

    const ImageProvider provider = ExactAssetImage('does-not-exist');
    final Object key = await provider.obtainKey(ImageConfiguration.empty);
    expect(imageCache!.statusForKey(provider).untracked, true);
    expect(imageCache!.pendingImageCount, 0);

    provider.resolve(ImageConfiguration.empty);

    expect(imageCache!.statusForKey(key).pending, true);
    expect(imageCache!.pendingImageCount, 1);

    await error.future;

    expect(imageCache!.statusForKey(provider).untracked, true);
    expect(imageCache!.pendingImageCount, 0);
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/56314

  test('ImageProvider can evict images', () async {
    final Uint8List bytes = Uint8List.fromList(kTransparentImage);
    final MemoryImage imageProvider = MemoryImage(bytes);
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    final Completer<void> completer = Completer<void>();
    stream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) => completer.complete()));
    await completer.future;

    expect(imageCache!.currentSize, 1);
    expect(await MemoryImage(bytes).evict(), true);
    expect(imageCache!.currentSize, 0);
  });

  test('ImageProvider.evict respects the provided ImageCache', () async {
    final ImageCache otherCache = ImageCache();
    final Uint8List bytes = Uint8List.fromList(kTransparentImage);
    final MemoryImage imageProvider = MemoryImage(bytes);
    final ImageStreamCompleter cacheStream = otherCache.putIfAbsent(
      imageProvider, () => imageProvider.load(imageProvider, _basicDecoder),
    )!;
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    final Completer<void> completer = Completer<void>();
    final Completer<void> cacheCompleter = Completer<void>();
    stream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
      completer.complete();
    }));
    cacheStream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
      cacheCompleter.complete();
    }));
    await Future.wait(<Future<void>>[completer.future, cacheCompleter.future]);

    expect(otherCache.currentSize, 1);
    expect(imageCache!.currentSize, 1);
    expect(await imageProvider.evict(cache: otherCache), true);
    expect(otherCache.currentSize, 0);
    expect(imageCache!.currentSize, 1);
  });

  test('ImageProvider errors can always be caught', () async {
    final ErrorImageProvider imageProvider = ErrorImageProvider();
    final Completer<bool> caughtError = Completer<bool>();
    FlutterError.onError = (FlutterErrorDetails details) {
      caughtError.complete(false);
    };
    final ImageStream stream = imageProvider.resolve(ImageConfiguration.empty);
    stream.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
      caughtError.complete(false);
    }, onError: (dynamic error, StackTrace? stackTrace) {
      caughtError.complete(true);
    }));
    expect(await caughtError.future, true);
  });
}
