// 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:convert' show jsonEncode;
import 'dart:developer' as developer;
import 'dart:ui' as ui;

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

void main() {
  late VmService vmService;
  late LiveTestWidgetsFlutterBinding binding;
  setUpAll(() async {
    final developer.ServiceProtocolInfo info =
        await developer.Service.getInfo();

    if (info.serverUri == null) {
      fail('This test _must_ be run with --enable-vmservice.');
    }

    vmService = await vmServiceConnectUri('ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws');
    await vmService.streamListen(EventStreams.kExtension);

    // Initialize bindings
    binding = LiveTestWidgetsFlutterBinding();
    binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
    binding.attachRootWidget(const SizedBox.expand());
    expect(binding.framesEnabled, true);
    // Pump two frames to make sure we clear out any inter-frame comparisons.
    await binding.endOfFrame;
    await binding.endOfFrame;
  });

  tearDownAll(() async {
    await vmService.dispose();
  });

  test('Image painting events - deduplicates across frames', () async {
    final Completer<Event> completer = Completer<Event>();
    vmService
        .onExtensionEvent
        .firstWhere((Event event) => event.extensionKind == 'Flutter.ImageSizesForFrame')
        .then(completer.complete);

    final ui.Image image = await createTestImage(width: 300, height: 300);
    final TestCanvas canvas = TestCanvas();
    paintImage(
      canvas: canvas,
      rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
      image: image,
      debugImageLabel: 'test.png',
    );

    // Make sure that we don't report an identical image size info if we
    // redraw in the next frame.
    await binding.endOfFrame;

    paintImage(
      canvas: canvas,
      rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
      image: image,
      debugImageLabel: 'test.png',
    );
    await binding.endOfFrame;

    final Event event = await completer.future;
    expect(event.extensionKind, 'Flutter.ImageSizesForFrame');
    expect(
      jsonEncode(event.extensionData!.data),
      contains('"test.png":{"source":"test.png","displaySize":{"width":600.0,"height":300.0},"imageSize":{"width":300.0,"height":300.0},"displaySizeInBytes":960000,"decodedSizeInBytes":480000}'),
    );
  }, skip: isBrowser); // [intended] uses dart:isolate and io.

  test('Image painting events - deduplicates across frames', () async {
    final Completer<Event> completer = Completer<Event>();
    vmService
        .onExtensionEvent
        .firstWhere((Event event) => event.extensionKind == 'Flutter.ImageSizesForFrame')
        .then(completer.complete);

    final ui.Image image = await createTestImage(width: 300, height: 300);
    final TestCanvas canvas = TestCanvas();
    paintImage(
      canvas: canvas,
      rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
      image: image,
      debugImageLabel: 'test.png',
    );

    paintImage(
      canvas: canvas,
      rect: const Rect.fromLTWH(50.0, 75.0, 300.0, 300.0),
      image: image,
      debugImageLabel: 'test.png',
    );
    await binding.endOfFrame;

    final Event event = await completer.future;
    expect(event.extensionKind, 'Flutter.ImageSizesForFrame');
    expect(
      jsonEncode(event.extensionData!.data),
      contains('"test.png":{"source":"test.png","displaySize":{"width":900.0,"height":900.0},"imageSize":{"width":300.0,"height":300.0},"displaySizeInBytes":4320000,"decodedSizeInBytes":480000}'),
    );
  }, skip: isBrowser); // [intended] uses dart:isolate and io.
}

class TestCanvas implements Canvas {
  @override
  void noSuchMethod(Invocation invocation) {}
}
