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

import 'package:test/test.dart';

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

import '../common/rendering.dart';
import '../common/test_initialization.dart';

export '../common/rendering.dart' show renderScene;

const MethodCodec codec = StandardMethodCodec();

/// Common test setup for all CanvasKit unit-tests.
void setUpCanvasKitTest({bool withImplicitView = false}) {
  setUpUnitTests(
    withImplicitView: withImplicitView,
    emulateTesterEnvironment: false,
    setUpTestViewDimensions: false,
  );

  setUp(() => debugOverrideJsConfiguration(<String, Object?>{
        'fontFallbackBaseUrl': 'assets/fallback_fonts/',
      }.jsify() as JsFlutterConfiguration?));
}

/// Convenience getter for the implicit view.
ui.FlutterView get implicitView =>
    EnginePlatformDispatcher.instance.implicitView!;

/// Utility function for CanvasKit tests to draw pictures without
/// the [CkPictureRecorder] boilerplate.
CkPicture paintPicture(
    ui.Rect cullRect, void Function(CkCanvas canvas) painter) {
  final CkPictureRecorder recorder = CkPictureRecorder();
  final CkCanvas canvas = recorder.beginRecording(cullRect);
  painter(canvas);
  return recorder.endRecording();
}

Future<void> matchSceneGolden(
  String goldenFile,
  ui.Scene scene, {
  required ui.Rect region,
}) async {
  await renderScene(scene);
  await matchGoldenFile(goldenFile, region: region);
}

/// Checks that a [picture] matches the [goldenFile].
///
/// The picture is drawn onto the UI at [ui.Offset.zero] with no additional
/// layers.
Future<void> matchPictureGolden(String goldenFile, CkPicture picture,
    {required ui.Rect region}) async {
  final LayerSceneBuilder sb = LayerSceneBuilder();
  sb.pushOffset(0, 0);
  sb.addPicture(ui.Offset.zero, picture);
  await renderScene(sb.build());
  await matchGoldenFile(goldenFile, region: region);
}

Future<bool> matchImage(ui.Image left, ui.Image right) async {
  if (left.width != right.width || left.height != right.height) {
    return false;
  }
  int getPixel(ByteData data, int x, int y) =>
      data.getUint32((x + y * left.width) * 4);
  final ByteData leftData = (await left.toByteData())!;
  final ByteData rightData = (await right.toByteData())!;
  for (int y = 0; y < left.height; y++) {
    for (int x = 0; x < left.width; x++) {
      if (getPixel(leftData, x, y) != getPixel(rightData, x, y)) {
        return false;
      }
    }
  }
  return true;
}

/// Sends a platform message to create a Platform View with the given id and viewType.
Future<void> createPlatformView(int id, String viewType) {
  final Completer<void> completer = Completer<void>();
  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/platform_views',
    codec.encodeMethodCall(MethodCall(
      'create',
      <String, dynamic>{
        'id': id,
        'viewType': viewType,
      },
    )),
    (dynamic _) => completer.complete(),
  );
  return completer.future;
}

/// Disposes of the platform view with the given [id].
Future<void> disposePlatformView(int id) {
  final Completer<void> completer = Completer<void>();
  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/platform_views',
    codec.encodeMethodCall(MethodCall('dispose', id)),
    (dynamic _) => completer.complete(),
  );
  return completer.future;
}

/// Creates a pre-laid out one-line paragraph of text.
///
/// Useful in tests that need a simple label to annotate goldens.
CkParagraph makeSimpleText(
  String text, {
  String? fontFamily,
  double? fontSize,
  ui.FontStyle? fontStyle,
  ui.FontWeight? fontWeight,
  ui.Color? color,
}) {
  final CkParagraphBuilder builder = CkParagraphBuilder(CkParagraphStyle(
    fontFamily: fontFamily ?? 'Roboto',
    fontSize: fontSize ?? 14,
    fontStyle: fontStyle ?? ui.FontStyle.normal,
    fontWeight: fontWeight ?? ui.FontWeight.normal,
  ));
  builder.pushStyle(CkTextStyle(
    color: color ?? const ui.Color(0xFF000000),
  ));
  builder.addText(text);
  builder.pop();
  final CkParagraph paragraph = builder.build();
  paragraph.layout(const ui.ParagraphConstraints(width: 10000));
  return paragraph;
}
