// 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:convert' show utf8, json;
import 'dart:isolate';
import 'dart:typed_data';
import 'dart:ui';

void main() {}

@pragma('vm:external-name', 'NativeReportTimingsCallback')
external void nativeReportTimingsCallback(List<int> timings);
@pragma('vm:external-name', 'NativeOnBeginFrame')
external void nativeOnBeginFrame(int microseconds);
@pragma('vm:external-name', 'NativeOnPointerDataPacket')
external void nativeOnPointerDataPacket(List<int> sequences);

@pragma('vm:entry-point')
void onErrorA() {
  PlatformDispatcher.instance.onError = (Object error, StackTrace? stack) {
    notifyErrorA(error.toString());
    return true;
  };
  Future<void>.delayed(const Duration(seconds: 2)).then((_) {
    throw Exception('I should be coming from A');
  });
}

@pragma('vm:entry-point')
void onErrorB() {
  PlatformDispatcher.instance.onError = (Object error, StackTrace? stack) {
    notifyErrorB(error.toString());
    return true;
  };
  throw Exception('I should be coming from B');
}

@pragma('vm:external-name', 'NotifyErrorA')
external void notifyErrorA(String message);
@pragma('vm:external-name', 'NotifyErrorB')
external void notifyErrorB(String message);

@pragma('vm:entry-point')
void drawFrames() {
  // Wait for native to tell us to start going.
  notifyNative();

  PlatformDispatcher.instance.onBeginFrame = (Duration beginTime) {
    final SceneBuilder builder = SceneBuilder();
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawPaint(Paint()..color = const Color(0xFFABCDEF));
    final Picture picture = recorder.endRecording();
    builder.addPicture(Offset.zero, picture);

    final Scene scene = builder.build();
    window.render(scene);

    scene.dispose();
    picture.dispose();
  };
  PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:entry-point')
void reportTimingsMain() {
  PlatformDispatcher.instance.onReportTimings = (List<FrameTiming> timings) {
    List<int> timestamps = [];
    for (FrameTiming t in timings) {
      for (FramePhase phase in FramePhase.values) {
        timestamps.add(t.timestampInMicroseconds(phase));
      }
    }
    nativeReportTimingsCallback(timestamps);
    PlatformDispatcher.instance.onReportTimings = (List<FrameTiming> timings) {};
  };
}

@pragma('vm:entry-point')
void onBeginFrameMain() {
  PlatformDispatcher.instance.onBeginFrame = (Duration beginTime) {
    nativeOnBeginFrame(beginTime.inMicroseconds);
  };
  PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:entry-point')
void onPointerDataPacketMain() {
  PlatformDispatcher.instance.onPointerDataPacket = (PointerDataPacket packet) {
    List<int> sequence = <int>[];
    for (PointerData data in packet.data) {
      sequence.add(PointerChange.values.indexOf(data.change));
    }
    nativeOnPointerDataPacket(sequence);
  };
}

@pragma('vm:entry-point')
void emptyMain() {}

@pragma('vm:entry-point')
void reportMetrics() {
  window.onMetricsChanged = () {
    _reportMetrics(
      window.devicePixelRatio,
      window.physicalSize.width,
      window.physicalSize.height,
    );
  };
}

@pragma('vm:external-name', 'ReportMetrics')
external void _reportMetrics(double devicePixelRatio, double width, double height);

@pragma('vm:entry-point')
void dummyReportTimingsMain() {
  PlatformDispatcher.instance.onReportTimings = (List<FrameTiming> timings) {};
}

@pragma('vm:entry-point')
void fixturesAreFunctionalMain() {
  sayHiFromFixturesAreFunctionalMain();
}

@pragma('vm:external-name', 'SayHiFromFixturesAreFunctionalMain')
external void sayHiFromFixturesAreFunctionalMain();

@pragma('vm:entry-point')
@pragma('vm:external-name', 'NotifyNative')
external void notifyNative();

@pragma('vm:entry-point')
void thousandCallsToNative() {
  for (int i = 0; i < 1000; i++) {
    notifyNative();
  }
}

void secondaryIsolateMain(String message) {
  print('Secondary isolate got message: ' + message);
  notifyNative();
}

@pragma('vm:entry-point')
void testCanLaunchSecondaryIsolate() {
  Isolate.spawn(secondaryIsolateMain, 'Hello from root isolate.');
  notifyNative();
}

@pragma('vm:entry-point')
void testSkiaResourceCacheSendsResponse() {
  final PlatformMessageResponseCallback callback = (ByteData? data) {
    if (data == null) {
      throw 'Response must not be null.';
    }
    final String response = utf8.decode(data.buffer.asUint8List());
    final List<bool> jsonResponse = json.decode(response).cast<bool>();
    if (jsonResponse[0] != true) {
      throw 'Response was not true';
    }
    notifyNative();
  };
  const String jsonRequest = '''{
                            "method": "Skia.setResourceCacheMaxBytes",
                            "args": 10000
                          }''';
  PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/skia',
    ByteData.sublistView(utf8.encode(jsonRequest)),
    callback,
  );
}

@pragma('vm:external-name', 'NotifyWidthHeight')
external void notifyWidthHeight(int width, int height);

@pragma('vm:entry-point')
void canCreateImageFromDecompressedData() {
  const int imageWidth = 10;
  const int imageHeight = 10;
  final Uint8List pixels = Uint8List.fromList(List<int>.generate(
    imageWidth * imageHeight * 4,
    (int i) => i % 4 < 2 ? 0x00 : 0xFF,
  ));

  decodeImageFromPixels(
    pixels,
    imageWidth,
    imageHeight,
    PixelFormat.rgba8888,
    (Image image) {
      notifyWidthHeight(image.width, image.height);
    },
  );
}

@pragma('vm:entry-point')
void canAccessIsolateLaunchData() {
  notifyMessage(
    utf8.decode(
      PlatformDispatcher.instance.getPersistentIsolateData()!.buffer.asUint8List(),
    ),
  );
}

@pragma('vm:entry-point')
void performanceModeImpactsNotifyIdle() {
  notifyNativeBool(false);
  PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.latency);
  notifyNativeBool(true);
  PlatformDispatcher.instance.requestDartPerformanceMode(DartPerformanceMode.balanced);
}

@pragma('vm:entry-point')
void callNotifyDestroyed() {
  notifyDestroyed();
}

@pragma('vm:external-name', 'NotifyMessage')
external void notifyMessage(String string);

@pragma('vm:entry-point')
void canRegisterImageDecoders() {
  decodeImageFromList(
    // The test ImageGenerator will always behave the same regardless of input.
    Uint8List(1),
    (Image result) {
      notifyWidthHeight(result.width, result.height);
    },
  );
}

@pragma('vm:external-name', 'NotifyLocalTime')
external void notifyLocalTime(String string);

@pragma('vm:external-name', 'WaitFixture')
external bool waitFixture();

// Return local date-time as a string, to an hour resolution.  So, "2020-07-23
// 14:03:22" will become "2020-07-23 14".
String localTimeAsString() {
   final now = DateTime.now().toLocal();
   // This is: "$y-$m-$d $h:$min:$sec.$ms$us";
   final timeStr = now.toString();
   // Forward only "$y-$m-$d $h" for timestamp comparison.  Not using DateTime
   // formatting since package:intl is not available.
  return timeStr.split(":")[0];
}

@pragma('vm:entry-point')
void localtimesMatch() {
  notifyLocalTime(localTimeAsString());
}

@pragma('vm:entry-point')
void timezonesChange() {
  do {
    notifyLocalTime(localTimeAsString());
  } while (waitFixture());
}

@pragma('vm:external-name', 'NotifyCanAccessResource')
external void notifyCanAccessResource(bool success);

@pragma('vm:external-name', 'NotifySetAssetBundlePath')
external void notifySetAssetBundlePath();

@pragma('vm:entry-point')
void canAccessResourceFromAssetDir() async {
  notifySetAssetBundlePath();
  window.sendPlatformMessage(
    'flutter/assets',
    ByteData.sublistView(utf8.encode('kernel_blob.bin')),
    (ByteData? byteData) {
      notifyCanAccessResource(byteData != null);
    },
  );
}

@pragma('vm:external-name', 'NotifyNativeWhenEngineRun')
external void notifyNativeWhenEngineRun(bool success);

@pragma('vm:external-name', 'NotifyNativeWhenEngineSpawn')
external void notifyNativeWhenEngineSpawn(bool success);

@pragma('vm:entry-point')
void canReceiveArgumentsWhenEngineRun(List<String> args) {
  notifyNativeWhenEngineRun(args.length == 2 && args[0] == 'foo' && args[1] == 'bar');
}

@pragma('vm:entry-point')
void canReceiveArgumentsWhenEngineSpawn(List<String> args) {
  notifyNativeWhenEngineSpawn(args.length == 2 && args[0] == 'arg1' && args[1] == 'arg2');
}

@pragma('vm:entry-point')
void onBeginFrameWithNotifyNativeMain() {
  PlatformDispatcher.instance.onBeginFrame = (Duration beginTime) {
    nativeOnBeginFrame(beginTime.inMicroseconds);
  };
  notifyNative();
}

@pragma('vm:entry-point')
void frameCallback(Object? image, int durationMilliseconds, String decodeError) {
  if (image == null) {
    throw Exception('Expeccted image in frame callback to be non-null');
  }
}

Picture CreateRedBox(Size size) {
  Paint paint = Paint()
    ..color = Color.fromARGB(255, 255, 0, 0)
    ..style = PaintingStyle.fill;
  PictureRecorder baseRecorder = PictureRecorder();
  Canvas canvas = Canvas(baseRecorder);
  canvas.drawRect(Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
  return baseRecorder.endRecording();
}

@pragma('vm:entry-point')
void scene_with_red_box() {
  PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
    SceneBuilder builder = SceneBuilder();
    builder.pushOffset(0.0, 0.0);
    builder.addPicture(Offset(0.0, 0.0), CreateRedBox(Size(2.0, 2.0)));
    builder.pop();
    PlatformDispatcher.instance.views.first.render(builder.build());
  };
  PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:external-name', 'NativeOnBeforeToImageSync')
external void onBeforeToImageSync();


@pragma('vm:entry-point')
Future<void> toImageSync() async {
  final PictureRecorder recorder = PictureRecorder();
  final Canvas canvas = Canvas(recorder);
  canvas.drawPaint(Paint()..color = const Color(0xFFAAAAAA));
  final Picture picture = recorder.endRecording();

  onBeforeToImageSync();
  final Image image = picture.toImageSync(20, 25);
  void expect(Object? a, Object? b) {
    if (a != b) {
      throw 'Expected $a to == $b';
    }
  }
  expect(image.width, 20);
  expect(image.height, 25);

  final ByteData dataBefore = (await image.toByteData())!;
  expect(dataBefore.lengthInBytes, 20 * 25 * 4);
  for (final int byte in dataBefore.buffer.asUint32List()) {
    expect(byte, 0xFFAAAAAA);
  }

  // Cause the rasterizer to get torn down.
  notifyNative();

  final ByteData dataAfter = (await image.toByteData())!;
  expect(dataAfter.lengthInBytes, 20 * 25 * 4);
  for (final int byte in dataAfter.buffer.asUint32List()) {
    expect(byte, 0xFFAAAAAA);
  }

  // Verify that the image can be drawn successfully.
  final PictureRecorder recorder2 = PictureRecorder();
  final Canvas canvas2 = Canvas(recorder2);
  canvas2.drawImage(image, Offset.zero, Paint());
  final Picture picture2 = recorder2.endRecording();

  picture.dispose();
  picture2.dispose();
  notifyNative();
}

@pragma('vm:entry-point')
Future<void> included() async {

}

Future<void> excluded() async {

}

class IsolateParam {
  const IsolateParam(this.sendPort, this.rawHandle);
  final SendPort sendPort;
  final int rawHandle;
}

@pragma('vm:entry-point')
Future<void> runCallback(IsolateParam param) async {
  try {
    final Future<dynamic> Function() func = PluginUtilities.getCallbackFromHandle(
      CallbackHandle.fromRawHandle(param.rawHandle)
    )! as Future<dynamic> Function();
    await func.call();
    param.sendPort.send(true);
  }
  on NoSuchMethodError {
    param.sendPort.send(false);
  }
}

@pragma('vm:entry-point')
@pragma('vm:external-name', 'NotifyNativeBool')
external void notifyNativeBool(bool value);
@pragma('vm:external-name', 'NotifyDestroyed')
external void notifyDestroyed();

@pragma('vm:entry-point')
Future<void> testPluginUtilitiesCallbackHandle() async {
  ReceivePort port = ReceivePort();
  await Isolate.spawn(
    runCallback,
    IsolateParam(
      port.sendPort,
      PluginUtilities.getCallbackHandle(included)!.toRawHandle()
    ),
    onError: port.sendPort
  );
  final dynamic result1 = await port.first;
  if (result1 != true) {
    print('Expected $result1 to == true');
    notifyNativeBool(false);
    return;
  }
  port.close();
  if (const bool.fromEnvironment('dart.vm.product')) {
    port = ReceivePort();
    await Isolate.spawn(
      runCallback,
      IsolateParam(
        port.sendPort,
        PluginUtilities.getCallbackHandle(excluded)!.toRawHandle()
      ),
      onError: port.sendPort
    );
    final dynamic result2 = await port.first;
    if (result2 != false) {
      print('Expected $result2 to == false');
      notifyNativeBool(false);
      return;
    }
    port.close();
  }
  notifyNativeBool(true);
}

@pragma('vm:entry-point')
Future<void> testThatAssetLoadingHappensOnWorkerThread() async {
  try {
    await ImmutableBuffer.fromAsset('DoesNotExist');
  } catch (err) { /* Do nothing */ }
  notifyNative();
}

@pragma('vm:external-name', 'NativeReportViewIdsCallback')
external void nativeReportViewIdsCallback(bool hasImplicitView, List<int> viewIds);

List<int> getCurrentViewIds() {
  final List<int> result = PlatformDispatcher.instance.views
      .map((FlutterView view) => view.viewId)
      .toList()
      ..sort();
  assert(result.toSet().length == result.length,
      'Unexpected duplicate view ID found: $result');
  return result;
}

bool listEquals<T>(List<T> a, List<T> b) {
  if (a.length != b.length) {
    return false;
  }
  for (int i = 0; i < a.length; i += 1) {
    if (a[i] != b[i]) {
      return false;
    }
  }
  return true;
}

// This entrypoint reports whether there's an implicit view and the list of view
// IDs using nativeReportViewIdsCallback on initialization and every time the
// list of view IDs changes.
@pragma('vm:entry-point')
void testReportViewIds() {
  List<int> viewIds = getCurrentViewIds();
  nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds);
  PlatformDispatcher.instance.onMetricsChanged = () {
    final List<int> newViewIds = getCurrentViewIds();
    if (!listEquals(viewIds, newViewIds)) {
      viewIds = newViewIds;
      nativeReportViewIdsCallback(PlatformDispatcher.instance.implicitView != null, viewIds);
    }
  };
}

// Returns a list of [view_id 1, view_width 1, view_id 2, view_width 2, ...]
// for all views.
List<int> getCurrentViewWidths() {
  final List<int> result = <int>[];
  for (final FlutterView view in PlatformDispatcher.instance.views) {
    result.add(view.viewId);
    result.add(view.physicalSize.width.round());
  }
  return result;
}

@pragma('vm:external-name', 'NativeReportViewWidthsCallback')
external void nativeReportViewWidthsCallback(List<int> viewWidthPacket);

// This entrypoint reports the list of views and their widths using
// nativeReportViewWidthsCallback on initialization and every onMetricsChanged.
@pragma('vm:entry-point')
void testReportViewWidths() {
  nativeReportViewWidthsCallback(getCurrentViewWidths());
  PlatformDispatcher.instance.onMetricsChanged = () {
    nativeReportViewWidthsCallback(getCurrentViewWidths());
  };
}

@pragma('vm:entry-point')
void onBeginFrameRendersMultipleViews() {
  PlatformDispatcher.instance.onBeginFrame = (Duration beginTime) {
    for (final FlutterView view in PlatformDispatcher.instance.views) {
      final SceneBuilder builder = SceneBuilder();
      final PictureRecorder recorder = PictureRecorder();
      final Canvas canvas = Canvas(recorder);
      canvas.drawPaint(Paint()..color = const Color(0xFFABCDEF));
      final Picture picture = recorder.endRecording();
      builder.addPicture(Offset.zero, picture);

      final Scene scene = builder.build();
      view.render(scene);

      scene.dispose();
      picture.dispose();
    }
  };
  notifyNative();
}
