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

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

// 1x1 transparent PNG bytes.
final Uint8List kTransparentImage = Uint8List.fromList(<int>[
  0x89,
  0x50,
  0x4E,
  0x47,
  0x0D,
  0x0A,
  0x1A,
  0x0A,
  0x00,
  0x00,
  0x00,
  0x0D,
  0x49,
  0x48,
  0x44,
  0x52,
  0x00,
  0x00,
  0x00,
  0x01,
  0x00,
  0x00,
  0x00,
  0x01,
  0x08,
  0x06,
  0x00,
  0x00,
  0x00,
  0x1F,
  0x15,
  0xC4,
  0x89,
  0x00,
  0x00,
  0x00,
  0x0A,
  0x49,
  0x44,
  0x41,
  0x54,
  0x78,
  0x9C,
  0x63,
  0x00,
  0x01,
  0x00,
  0x00,
  0x05,
  0x00,
  0x01,
  0x0D,
  0x0A,
  0x2D,
  0xB4,
  0x00,
  0x00,
  0x00,
  0x00,
  0x49,
  0x45,
  0x4E,
  0x44,
  0xAE,
  0x42,
  0x60,
  0x82,
]);

void main() {
  test('createTestImage creates and caches an image', () async {
    final ui.Image image1 = await createTestImage(width: 10, height: 10);
    expect(image1.width, 10);
    expect(image1.height, 10);
    image1.dispose();

    final ui.Image image2 = await createTestImage(width: 10, height: 10);
    expect(image2.width, 10);
    expect(image2.height, 10);
    image2.dispose();
  });

  test('precacheTestImage can be used in a standalone test', () async {
    final provider = MemoryImage(kTransparentImage);
    await precacheTestImage(provider);
    expect(imageCache.containsKey(provider), isTrue);
    imageCache.clear();
    imageCache.clearLiveImages();
  });

  testWidgets('precacheTestImage synchronously loads image into ImageCache for first frame', (
    WidgetTester tester,
  ) async {
    addTearDown(imageCache.clear);
    addTearDown(imageCache.clearLiveImages);
    final provider = MemoryImage(kTransparentImage);
    await precacheTestImage(provider);

    bool? wasSynchronouslyLoaded;
    await tester.pumpWidget(
      Image(
        image: provider,
        frameBuilder: (BuildContext context, Widget child, int? frame, bool synchronouslyLoaded) {
          wasSynchronouslyLoaded = synchronouslyLoaded;
          return child;
        },
      ),
    );

    expect(wasSynchronouslyLoaded, isTrue);
  });

  testWidgets('precacheTestImage reports errors to onError handler', (WidgetTester tester) async {
    final errorProvider = _FailingImageProvider();
    Object? caughtError;
    StackTrace? caughtStackTrace;

    await precacheTestImage(
      errorProvider,
      onError: (Object error, StackTrace? stackTrace) {
        caughtError = error;
        caughtStackTrace = stackTrace;
      },
    );

    expect(caughtError, isA<StateError>());
    expect(caughtStackTrace, isNotNull);
    imageCache.clear();
    imageCache.clearLiveImages();
    await tester.pump();
  });

  testWidgets('precacheTestImage throws if onError is not provided and load fails', (
    WidgetTester tester,
  ) async {
    final errorProvider = _FailingImageProvider();

    await expectLater(() => precacheTestImage(errorProvider), throwsA(isA<StateError>()));
    imageCache.clear();
    imageCache.clearLiveImages();
    await tester.pump();
  });
}

class _FailingImageProvider extends ImageProvider<Object> {
  @override
  Future<Object> obtainKey(ImageConfiguration configuration) {
    return Future<Object>.value(this);
  }

  @override
  ImageStreamCompleter loadImage(Object key, ImageDecoderCallback decode) {
    return OneFrameImageStreamCompleter(
      Future<ImageInfo>.error(StateError('Failed to load test image')),
    );
  }
}
