// 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:io' as io;
import 'dart:typed_data' show ByteData, Endian, Uint8List;
import 'dart:ui' as ui;
import 'dart:convert';

// Signals a waiting latch in the native test.
@pragma('vm:external-name', 'Signal')
external void signal();

// Signals a waiting latch in the native test, passing a boolean value.
@pragma('vm:external-name', 'SignalBoolValue')
external void signalBoolValue(bool value);

// Signals a waiting latch in the native test, passing a string value.
@pragma('vm:external-name', 'SignalStringValue')
external void signalStringValue(String value);

// Signals a waiting latch in the native test, which returns a value to the fixture.
@pragma('vm:external-name', 'SignalBoolReturn')
external bool signalBoolReturn();

// Notify the native test that the first frame has been scheduled.
@pragma('vm:external-name', 'NotifyFirstFrameScheduled')
external void notifyFirstFrameScheduled();

void main() {}

@pragma('vm:entry-point')
void hiPlatformChannels() {
  ui.channelBuffers.setListener('hi',
      (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
    ui.PlatformDispatcher.instance.sendPlatformMessage('hi', data,
        (ByteData? reply) {
      ui.PlatformDispatcher.instance
          .sendPlatformMessage('hi', reply, (ByteData? reply) {});
    });
    callback(data);
  });
}

/// Returns a future that completes when
/// `PlatformDispatcher.instance.onSemanticsEnabledChanged` fires.
Future<void> get semanticsChanged {
  final Completer<void> semanticsChanged = Completer<void>();
  ui.PlatformDispatcher.instance.onSemanticsEnabledChanged =
      semanticsChanged.complete;
  return semanticsChanged.future;
}

@pragma('vm:entry-point')
void sendAccessibilityAnnouncement() async {
  // Wait until semantics are enabled.
  if (!ui.PlatformDispatcher.instance.semanticsEnabled) {
    await semanticsChanged;
  }

  // Standard message codec magic number identifiers.
  // See: https://github.com/flutter/flutter/blob/ee94fe262b63b0761e8e1f889ae52322fef068d2/packages/flutter/lib/src/services/message_codecs.dart#L262
  const int valueMap = 13, valueString = 7;

  // Corresponds to: {"type": "announce", "data": {"message": "hello"}}
  // See: https://github.com/flutter/flutter/blob/b781da9b5822de1461a769c3b245075359f5464d/packages/flutter/lib/src/semantics/semantics_event.dart#L86
  final Uint8List data = Uint8List.fromList([
    // Map with 2 entries
    valueMap, 2,
    // Map key: "type"
    valueString, 'type'.length, ...'type'.codeUnits,
    // Map value: "announce"
    valueString, 'announce'.length, ...'announce'.codeUnits,
    // Map key: "data"
    valueString, 'data'.length, ...'data'.codeUnits,
    // Map value: map with 1 entry
    valueMap, 1,
    // Map key: "message"
    valueString, 'message'.length, ...'message'.codeUnits,
    // Map value: "hello"
    valueString, 'hello'.length, ...'hello'.codeUnits,
  ]);
  final ByteData byteData = data.buffer.asByteData();

  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/accessibility',
    byteData,
    (ByteData? _) => signal(),
  );
}

@pragma('vm:entry-point')
void sendAccessibilityTooltipEvent() async {
  // Wait until semantics are enabled.
  if (!ui.PlatformDispatcher.instance.semanticsEnabled) {
    await semanticsChanged;
  }

  // Standard message codec magic number identifiers.
  // See: https://github.com/flutter/flutter/blob/ee94fe262b63b0761e8e1f889ae52322fef068d2/packages/flutter/lib/src/services/message_codecs.dart#L262
  const int valueMap = 13, valueString = 7;

  // Corresponds to: {"type": "tooltip", "data": {"message": "hello"}}
  // See: https://github.com/flutter/flutter/blob/b781da9b5822de1461a769c3b245075359f5464d/packages/flutter/lib/src/semantics/semantics_event.dart#L120
  final Uint8List data = Uint8List.fromList([
    // Map with 2 entries
    valueMap, 2,
    // Map key: "type"
    valueString, 'type'.length, ...'type'.codeUnits,
    // Map value: "tooltip"
    valueString, 'tooltip'.length, ...'tooltip'.codeUnits,
    // Map key: "data"
    valueString, 'data'.length, ...'data'.codeUnits,
    // Map value: map with 1 entry
    valueMap, 1,
    // Map key: "message"
    valueString, 'message'.length, ...'message'.codeUnits,
    // Map value: "hello"
    valueString, 'hello'.length, ...'hello'.codeUnits,
  ]);
  final ByteData byteData = data.buffer.asByteData();

  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/accessibility',
    byteData,
    (ByteData? _) => signal(),
  );
}

@pragma('vm:entry-point')
void exitTestExit() async {
  final Completer<ByteData?> closed = Completer<ByteData?>();
  ui.channelBuffers.setListener('flutter/platform', (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
    final String jsonString = json.encode(<Map<String, String>>[{'response': 'exit'}]);
    final ByteData responseData = ByteData.sublistView(utf8.encode(jsonString));
    callback(responseData);
    closed.complete(data);
  });
  await closed.future;
}

@pragma('vm:entry-point')
void exitTestCancel() async {
  final Completer<ByteData?> closed = Completer<ByteData?>();
  ui.channelBuffers.setListener('flutter/platform', (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
    final String jsonString = json.encode(<Map<String, String>>[{'response': 'cancel'}]);
    final ByteData responseData = ByteData.sublistView(utf8.encode(jsonString));
    callback(responseData);
    closed.complete(data);
  });
  await closed.future;

  // Because the request was canceled, the below shall execute.
  final Completer<ByteData?> exited = Completer<ByteData?>();
  final String jsonString = json.encode(<String, dynamic>{
    'method': 'System.exitApplication',
    'args': <String, dynamic>{
      'type': 'required', 'exitCode': 0
      }
    });
  ui.PlatformDispatcher.instance.sendPlatformMessage(
    'flutter/platform',
    ByteData.sublistView(utf8.encode(jsonString)),
    (ByteData? reply) {
      exited.complete(reply);
    });
  await exited.future;
}

@pragma('vm:entry-point')
void enableLifecycleTest() async {
  final Completer<ByteData?> finished = Completer<ByteData?>();
  ui.channelBuffers.setListener('flutter/lifecycle', (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
    if (data != null) {
      ui.PlatformDispatcher.instance.sendPlatformMessage(
        'flutter/unittest',
        data,
        (ByteData? reply) {
          finished.complete();
        });
    }
  });
  await finished.future;
}

@pragma('vm:entry-point')
void enableLifecycleToFrom() async {
  ui.channelBuffers.setListener('flutter/lifecycle', (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
    if (data != null) {
      ui.PlatformDispatcher.instance.sendPlatformMessage(
        'flutter/unittest',
        data,
        (ByteData? reply) {});
    }
  });
  final Completer<ByteData?> enabledLifecycle = Completer<ByteData?>();
  ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/platform', ByteData.sublistView(utf8.encode('{"method":"System.initializationComplete"}')), (ByteData? data) {
    enabledLifecycle.complete(data);
  });
}

@pragma('vm:entry-point')
void sendCreatePlatformViewMethod() async {
  // The platform view method channel uses the standard method codec.
  // See https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/message_codecs.dart#L262
  // for the implementation of the encoding and magic number identifiers.
  const int valueString = 7;
  const int valueMap = 13;
  const int valueInt32 = 3;
  const String method = 'create';
  const String typeKey = 'viewType';
  const String typeValue = 'type';
  const String idKey = 'id';
  final List<int> data = <int>[
    // Method name
    valueString, method.length, ...utf8.encode(method),
    // Method arguments: {'type': 'type':, 'id': 0}
    valueMap, 2,
    valueString, typeKey.length, ...utf8.encode(typeKey),
    valueString, typeValue.length, ...utf8.encode(typeValue),
    valueString, idKey.length, ...utf8.encode(idKey),
    valueInt32, 0, 0, 0, 0,
  ];

  final Completer<ByteData?> completed = Completer<ByteData?>();
  final ByteData bytes = ByteData.sublistView(Uint8List.fromList(data));
  ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/platform_views', bytes, (ByteData? response) {
    completed.complete(response);
  });
  await completed.future;
}

@pragma('vm:entry-point')
void sendGetKeyboardState() async {
  // The keyboard method channel uses the standard method codec.
  // See https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/services/message_codecs.dart#L262
  // for the implementation of the encoding and magic number identifiers.
  const int valueNull = 0;
  const int valueString = 7;
  const int valueMap = 13;

  const String method = 'getKeyboardState';
  final List<int> data = <int>[
    // Method name
    valueString, method.length, ...utf8.encode(method),
    // Method arguments: null
    valueNull, 2,
  ];

  final Completer<void> completer = Completer<void>();
  final ByteData bytes = ByteData.sublistView(Uint8List.fromList(data));
  ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/keyboard', bytes, (ByteData? response) {
    // For magic numbers for decoding a reply envelope, see:
    // https://github.com/flutter/flutter/blob/67271f69f7f88a4edba6d8023099e3bd27a072d2/packages/flutter/lib/src/services/message_codecs.dart#L577-L587
    const int replyEnvelopeSuccess = 0;

    // Ensure the response is a success containing a map of keyboard states.
    if (response == null) {
      signalStringValue('Unexpected null response');
    } else if (response.lengthInBytes < 2) {
      signalStringValue('Unexpected response length of ${response.lengthInBytes} bytes');
    } else if (response.getUint8(0) != replyEnvelopeSuccess) {
      signalStringValue('Unexpected response envelope status: ${response.getUint8(0)}');
    } else if (response.getUint8(1) != valueMap) {
      signalStringValue('Unexpected response value magic number: ${response.getUint8(1)}');
    } else {
      signalStringValue('Success');
    }
    completer.complete();
  });
  await completer.future;
}

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

@pragma('vm:entry-point')
void verifyNativeFunction() {
  signal();
}

@pragma('vm:entry-point')
void verifyNativeFunctionWithParameters() {
  signalBoolValue(true);
}

@pragma('vm:entry-point')
void verifyNativeFunctionWithReturn() {
  bool value = signalBoolReturn();
  signalBoolValue(value);
}

@pragma('vm:entry-point')
void readPlatformExecutable() {
  signalStringValue(io.Platform.executable);
}

@pragma('vm:entry-point')
void drawHelloWorld() {
  ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
    final ui.ParagraphBuilder paragraphBuilder =
        ui.ParagraphBuilder(ui.ParagraphStyle())..addText('Hello world');
    final ui.Paragraph paragraph = paragraphBuilder.build();

    paragraph.layout(const ui.ParagraphConstraints(width: 800.0));

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

    canvas.drawParagraph(paragraph, ui.Offset.zero);

    final ui.Picture picture = recorder.endRecording();
    final ui.SceneBuilder sceneBuilder = ui.SceneBuilder()
      ..addPicture(ui.Offset.zero, picture)
      ..pop();

    ui.PlatformDispatcher.instance.implicitView?.render(sceneBuilder.build());
  };

  ui.PlatformDispatcher.instance.scheduleFrame();
  notifyFirstFrameScheduled();
}

ui.Picture _createColoredBox(ui.Color color, ui.Size size) {
  final ui.Paint paint = ui.Paint();
  paint.color = color;
  final ui.PictureRecorder baseRecorder = ui.PictureRecorder();
  final ui.Canvas canvas = ui.Canvas(baseRecorder);
  canvas.drawRect(ui.Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
  return baseRecorder.endRecording();
}

@pragma('vm:entry-point')
void renderImplicitView() {
  ui.PlatformDispatcher.instance.onBeginFrame = (Duration duration) {
    final ui.Size size = ui.Size(800.0, 600.0);
    final ui.Color red = ui.Color.fromARGB(127, 255, 0, 0);

    final ui.SceneBuilder builder = ui.SceneBuilder();

    builder.pushOffset(0.0, 0.0);

    builder.addPicture(
        ui.Offset(0.0, 0.0), _createColoredBox(red, size));

    builder.pop();

    ui.PlatformDispatcher.instance.implicitView?.render(builder.build());
  };
  ui.PlatformDispatcher.instance.scheduleFrame();
}

@pragma('vm:entry-point')
void signalViewIds() {
  final Iterable<ui.FlutterView> views = ui.PlatformDispatcher.instance.views;
  final List<int> viewIds =
      views.map((ui.FlutterView view) => view.viewId).toList();

  viewIds.sort();

  signalStringValue('View IDs: [${viewIds.join(', ')}]');
}

@pragma('vm:entry-point')
void onMetricsChangedSignalViewIds() {
  ui.PlatformDispatcher.instance.onMetricsChanged = () {
    signalViewIds();
  };

  signal();
}
