// Copyright 2013 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 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

import '../common/matchers.dart';
import 'common.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  group('CkPicture', () {
    setUpCanvasKitTest();

    group('lifecycle', () {
      test('can be disposed of manually', () {
        final ui.PictureRecorder recorder = ui.PictureRecorder();
        final ui.Canvas canvas = ui.Canvas(recorder);
        canvas.drawPaint(ui.Paint());
        final CkPicture picture = recorder.endRecording() as CkPicture;
        expect(picture.skiaObject, isNotNull);
        expect(picture.debugDisposed, isFalse);
        picture.debugCheckNotDisposed('Test.'); // must not throw
        picture.dispose();
        expect(() => picture.skiaObject, throwsA(isAssertionError));
        expect(picture.debugDisposed, isTrue);

        StateError? actualError;
        try {
          picture.debugCheckNotDisposed('Test.');
        } on StateError catch (error) {
          actualError = error;
        }

        expect(actualError, isNotNull);

        // TODO(yjbanov): cannot test precise message due to https://github.com/flutter/flutter/issues/96298
        expect(
            '$actualError',
            startsWith('Bad state: Test.\n'
                'The picture has been disposed. '
                'When the picture was disposed the stack trace was:\n'));
      });
    });

    test('toImageSync', () async {
      const ui.Color color = ui.Color(0xFFAAAAAA);
      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawPaint(ui.Paint()..color = color);
      final ui.Picture picture = recorder.endRecording();
      final ui.Image image = picture.toImageSync(10, 15);

      expect(image.width, 10);
      expect(image.height, 15);

      final ByteData? data = await image.toByteData();
      expect(data, isNotNull);
      expect(data!.lengthInBytes, 10 * 15 * 4);
      expect(data.buffer.asUint32List().first, color.value);
    });

    test('cullRect bounds are tight', () async {
      const ui.Color red = ui.Color.fromRGBO(255, 0, 0, 1);
      const ui.Color green = ui.Color.fromRGBO(0, 255, 0, 1);
      const ui.Color blue = ui.Color.fromRGBO(0, 0, 255, 1);

      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawRRect(
        ui.RRect.fromRectXY(const ui.Rect.fromLTRB(20, 20, 150, 300), 15, 15),
        ui.Paint()..color = red,
      );
      canvas.drawCircle(
        const ui.Offset(200, 200),
        100,
        ui.Paint()..color = green,
      );
      canvas.drawOval(
        const ui.Rect.fromLTRB(210, 40, 268, 199),
        ui.Paint()..color = blue,
      );

      final CkPicture picture = recorder.endRecording() as CkPicture;
      final ui.Rect bounds = picture.cullRect;
      // Top left bounded by the red rrect, right bounded by right edge
      // of red rrect, bottom bounded by bottom of green circle.
      expect(bounds, equals(const ui.Rect.fromLTRB(20, 20, 300, 300)));
    });

    test('cullRect bounds with infinite size draw', () async {
      const ui.Color red = ui.Color.fromRGBO(255, 0, 0, 1);

      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawColor(red, ui.BlendMode.src);

      final CkPicture picture = recorder.endRecording() as CkPicture;
      final ui.Rect bounds = picture.cullRect;
      // Since the drawColor command fills the entire canvas, the computed
      // bounds default to the cullRect that is passed in when the
      // PictureRecorder is created, ie ui.Rect.largest.
      expect(bounds, equals(ui.Rect.largest));
    });

    test('approximateBytesUsed', () async {
      const ui.Color red = ui.Color.fromRGBO(255, 0, 0, 1);
      const ui.Color green = ui.Color.fromRGBO(0, 255, 0, 1);
      const ui.Color blue = ui.Color.fromRGBO(0, 0, 255, 1);

      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawRRect(
        ui.RRect.fromRectXY(const ui.Rect.fromLTRB(20, 20, 150, 300), 15, 15),
        ui.Paint()..color = red,
      );
      canvas.drawCircle(
        const ui.Offset(200, 200),
        100,
        ui.Paint()..color = green,
      );
      canvas.drawOval(
        const ui.Rect.fromLTRB(210, 40, 268, 199),
        ui.Paint()..color = blue,
      );

      final CkPicture picture = recorder.endRecording() as CkPicture;
      final int bytesUsed = picture.approximateBytesUsed;
      // Sanity check: the picture should use more than 20 bytes of memory.
      expect(bytesUsed, greaterThan(20));
    });
    // TODO(hterkelsen): https://github.com/flutter/flutter/issues/60040
  }, skip: isIosSafari);
}
