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

import 'package:litetest/litetest.dart';
import 'package:path/path.dart' as path;

void main() {
  bool assertsEnabled = false;
  assert(() {
    assertsEnabled = true;
    return true;
  }());

  test('Handles are distinct', () async {
    final Uint8List bytes = await readFile('2x2.png');
    final Codec codec = await instantiateImageCodec(bytes);
    final FrameInfo frame = await codec.getNextFrame();

    expect(frame.image.width, 2);
    expect(frame.image.height, 2);
    final Image handle1 = frame.image.clone();
    expect(handle1.width, frame.image.width);
    expect(handle1.height, frame.image.height);

    final Image handle2 = handle1.clone();
    expect(handle1 != handle2, true);
    expect(handle1 != frame.image, true);
    expect(frame.image == frame.image, true);

    frame.image.dispose();
  });

  test('Canvas can paint image from handle and byte data from handle', () async {
    final Uint8List bytes = await readFile('2x2.png');
    final Codec codec = await instantiateImageCodec(bytes);
    final FrameInfo frame = await codec.getNextFrame();

    expect(frame.image.width, 2);
    expect(frame.image.height, 2);
    final Image handle1 = frame.image.clone();

    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);

    const Rect rect = Rect.fromLTRB(0, 0, 2, 2);
    canvas.drawImage(handle1, Offset.zero, Paint());
    canvas.drawImageRect(handle1, rect, rect, Paint());
    canvas.drawImageNine(handle1, rect, rect, Paint());
    canvas.drawAtlas(handle1, <RSTransform>[], <Rect>[], <Color>[], BlendMode.src, rect, Paint());
    canvas.drawRawAtlas(handle1, Float32List(0), Float32List(0), Int32List(0), BlendMode.src, rect, Paint());

    final Picture picture = recorder.endRecording();

    final Image rasterizedImage = await picture.toImage(2, 2);
    final ByteData sourceData = (await frame.image.toByteData())!;
    final ByteData handleData = (await handle1.toByteData())!;
    final ByteData rasterizedData = (await rasterizedImage.toByteData())!;

    expect(sourceData.buffer.asUint8List(), equals(handleData.buffer.asUint8List()));
    expect(sourceData.buffer.asUint8List(), equals(rasterizedData.buffer.asUint8List()));
  });

  test('Records stack traces', () async {
    final Uint8List bytes = await readFile('2x2.png');
    final Codec codec = await instantiateImageCodec(bytes);
    final FrameInfo frame = await codec.getNextFrame();

    final Image handle1 = frame.image.clone();
    final Image handle2 = handle1.clone();

    List<StackTrace> stackTraces = (frame.image.debugGetOpenHandleStackTraces())!;
    expect(stackTraces.length, 3);
    expect(stackTraces, equals(handle1.debugGetOpenHandleStackTraces()));

    handle1.dispose();
    stackTraces = (frame.image.debugGetOpenHandleStackTraces())!;
    expect(stackTraces.length, 2);
    expect(stackTraces, equals(handle2.debugGetOpenHandleStackTraces()));

    handle2.dispose();
    stackTraces = (frame.image.debugGetOpenHandleStackTraces())!;
    expect(stackTraces.length, 1);
    expect(stackTraces, equals(frame.image.debugGetOpenHandleStackTraces()));

    frame.image.dispose();
    expect(frame.image.debugGetOpenHandleStackTraces(), isEmpty);
  }, skip: !assertsEnabled);

  test('Clones can be compared', () async {
    final Uint8List bytes = await readFile('2x2.png');
    final Codec codec = await instantiateImageCodec(bytes);
    final FrameInfo frame = await codec.getNextFrame();

    final Image handle1 = frame.image.clone();
    final Image handle2 = handle1.clone();

    expect(handle1.isCloneOf(handle2), true);
    expect(handle2.isCloneOf(handle1), true);
    expect(handle1.isCloneOf(frame.image), true);

    handle1.dispose();
    expect(handle1.isCloneOf(handle2), true);
    expect(handle2.isCloneOf(handle1), true);
    expect(handle1.isCloneOf(frame.image), true);

    final Codec codec2 = await instantiateImageCodec(bytes);
    final FrameInfo frame2 = await codec2.getNextFrame();

    expect(frame2.image.isCloneOf(frame.image), false);
  });

  test('debugDisposed works', () async {
    final Uint8List bytes = await readFile('2x2.png');
    final Codec codec = await instantiateImageCodec(bytes);
    final FrameInfo frame = await codec.getNextFrame();

    if (assertsEnabled) {
      expect(frame.image.debugDisposed, false);
    } else {
      expect(() => frame.image.debugDisposed, throwsStateError);
    }

    frame.image.dispose();
    if (assertsEnabled) {
      expect(frame.image.debugDisposed, true);
    } else {
      expect(() => frame.image.debugDisposed, throwsStateError);
    }
  });
}

Future<Uint8List> readFile(String fileName) async {
  final File file = File(path.join(
    'flutter',
    'testing',
    'resources',
    fileName,
  ));
  return file.readAsBytes();
}
