// 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.

// @dart = 2.6
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:vector_math/vector_math_64.dart';

import 'scenario.dart';
import 'scenarios.dart';

List<int> _to32(int value) {
  final Uint8List temp = Uint8List(4);
  temp.buffer.asByteData().setInt32(0, value, Endian.little);
  return temp;
}

List<int> _to64(num value) {
  final Uint8List temp = Uint8List(15);
  if (value is double) {
    temp.buffer.asByteData().setFloat64(7, value, Endian.little);
  } else if (value is int) {
    temp.buffer.asByteData().setInt64(7, value, Endian.little);
  }
  return temp;
}

/// A simple platform view.
class PlatformViewScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// A simple platform view with overlay that doesn't intersect with the platform view.
class PlatformViewNoOverlayIntersectionScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewNoOverlayIntersectionScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    finishBuilderByAddingPlatformViewAndPicture(
      builder,
      id,
      overlayOffset: const Offset(150, 350),
    );
  }
}

/// A simple platform view with an overlay that partially intersects with the platform view.
class PlatformViewPartialIntersectionScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewPartialIntersectionScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier .
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    finishBuilderByAddingPlatformViewAndPicture(
      builder,
      id,
      overlayOffset: const Offset(150, 250),
    );
  }
}

/// A simple platform view with two overlays that intersect with each other and the platform view.
class PlatformViewTwoIntersectingOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewTwoIntersectingOverlaysScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    _addPlatformViewtoScene(builder, id, 500, 500);
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawCircle(
      const Offset(50, 50),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(100, 100),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    final Picture picture = recorder.endRecording();
    builder.addPicture(const Offset(300, 300), picture);
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();
  }
}

/// A simple platform view with one overlay and two overlays that intersect with each other and the platform view.
class PlatformViewOneOverlayTwoIntersectingOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewOneOverlayTwoIntersectingOverlaysScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    _addPlatformViewtoScene(builder, id, 500, 500);
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawCircle(
      const Offset(50, 50),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(100, 100),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(-100, 200),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    final Picture picture = recorder.endRecording();
    builder.addPicture(const Offset(300, 300), picture);
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();
  }
}

/// Two platform views without an overlay intersecting either platform view.
class MultiPlatformViewWithoutOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  MultiPlatformViewWithoutOverlaysScenario(Window window, String text, { this.firstId, this.secondId })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, firstId);
    createPlatformView(window, text, secondId);
  }

  /// The platform view identifier to use for the first platform view.
  final int firstId;

  /// The platform view identifier to use for the second platform view.
  final int secondId;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    builder.pushOffset(0, 600);
    _addPlatformViewtoScene(builder, firstId, 500, 500);
    builder.pop();

    _addPlatformViewtoScene(builder, secondId, 500, 500);

    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawRect(
      const Rect.fromLTRB(0, 0, 100, 1000),
      Paint()..color = const Color(0xFFFF0000),
    );
    final Picture picture = recorder.endRecording();
    builder.addPicture(const Offset(580, 0), picture);

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

/// A simple platform view with too many overlays result in a single native view.
class PlatformViewMaxOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewMaxOverlaysScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    _addPlatformViewtoScene(builder, id, 500, 500);
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawCircle(
      const Offset(50, 50),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(100, 100),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(-100, 200),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    canvas.drawCircle(
      const Offset(-100, -80),
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    final Picture picture = recorder.endRecording();
    builder.addPicture(const Offset(300, 300), picture);
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();
  }
}

/// Builds a scene with 2 platform views.
class MultiPlatformViewScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  MultiPlatformViewScenario(Window window, {this.firstId, this.secondId})
      : assert(window != null),
        super(window) {
    createPlatformView(window, 'platform view 1', firstId);
    createPlatformView(window, 'platform view 2', secondId);
  }

  /// The platform view identifier to use for the first platform view.
  final int firstId;

  /// The platform view identifier to use for the second platform view.
  final int secondId;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    builder.pushOffset(0, 600);
    _addPlatformViewtoScene(builder, firstId, 500, 500);
    builder.pop();

    finishBuilderByAddingPlatformViewAndPicture(builder, secondId);
  }
}

/// Scenario for verifying platform views after background and foregrounding the app.
///
/// Renders a frame with 2 platform views covered by a flutter drawn rectangle,
/// when the app goes to the background and comes back to the foreground renders a new frame
/// with the 2 platform views but without the flutter drawn rectangle.
class MultiPlatformViewBackgroundForegroundScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  MultiPlatformViewBackgroundForegroundScenario(Window window, {this.firstId, this.secondId})
      : assert(window != null),
        super(window) {
    createPlatformView(window, 'platform view 1', firstId);
    createPlatformView(window, 'platform view 2', secondId);
    _nextFrame = _firstFrame;
  }

  /// The platform view identifier to use for the first platform view.
  final int firstId;

  /// The platform view identifier to use for the second platform view.
  final int secondId;

  @override
  void onBeginFrame(Duration duration) {
    _nextFrame();
  }

  VoidCallback _nextFrame;

  void _firstFrame() {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    builder.pushOffset(0, 600);
    _addPlatformViewtoScene(builder, firstId, 500, 500);
    builder.pop();

    _addPlatformViewtoScene(builder, secondId, 500, 500);

    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawRect(
      const Rect.fromLTRB(0, 0, 500, 1000),
      Paint()..color = const Color(0xFFFF0000),
    );
    final Picture picture = recorder.endRecording();
    builder.addPicture(const Offset(0, 0), picture);

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

  void _secondFrame() {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    builder.pushOffset(0, 600);
    _addPlatformViewtoScene(builder, firstId, 500, 500);
    builder.pop();

    _addPlatformViewtoScene(builder, secondId, 500, 500);
    final Scene scene = builder.build();
    window.render(scene);
    scene.dispose();
  }

  String _lastLifecycleState = '';

  @override
  void onPlatformMessage(
      String name,
      ByteData data,
      PlatformMessageResponseCallback callback,
      ) {
    if (name != 'flutter/lifecycle') {
      return;
    }
    final String message = utf8.decode(data.buffer.asUint8List());
    if (_lastLifecycleState == 'AppLifecycleState.inactive' && message == 'AppLifecycleState.resumed') {
      _nextFrame = _secondFrame;
      window.scheduleFrame();
    }

    _lastLifecycleState = message;
  }
}

/// Platform view with clip rect.
class PlatformViewClipRectScenario extends Scenario with _BasePlatformViewScenarioMixin {
  /// Constructs a platform view with clip rect scenario.
  PlatformViewClipRectScenario(Window window, String text, { this.id })
      : assert(window != null),
        super(window) {
    createPlatformView(window, text, id);
  }

  /// The platform view identifier.
  final int id;

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();
    builder.pushOffset(0, 0);
    builder.pushClipRect(const Rect.fromLTRB(100, 100, 400, 400));
    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// Platform view with clip rrect.
class PlatformViewClipRRectScenario extends PlatformViewScenario {
  /// Constructs a platform view with clip rrect scenario.
  PlatformViewClipRRectScenario(Window window, String text, { int id = 0 })
      : super(window, text, id: id);

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);
    builder.pushClipRRect(
      RRect.fromLTRBAndCorners(
        100,
        100,
        400,
        400,
        topLeft: const Radius.circular(15),
        topRight: const Radius.circular(50),
        bottomLeft: const Radius.circular(50),
      ),
    );
    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// Platform view with clip path.
class PlatformViewClipPathScenario extends PlatformViewScenario {
  /// Constructs a platform view with clip rrect scenario.
  PlatformViewClipPathScenario(Window window, String text, { int id = 0 })
      : super(window, text, id: id);

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);

    final Path path = Path()
      ..moveTo(100, 100)
      ..quadraticBezierTo(50, 250, 100, 400)
      ..lineTo(350, 400)
      ..cubicTo(400, 300, 300, 200, 350, 100)
      ..close();
    builder.pushClipPath(path);

    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// Platform view with transform.
class PlatformViewTransformScenario extends PlatformViewScenario {
  /// Constructs a platform view with transform scenario.
  PlatformViewTransformScenario(Window window, String text, { int id = 0 })
      : super(window, text, id: id);

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);
    final Matrix4 matrix4 = Matrix4.identity()
      ..rotateZ(1)
      ..scale(0.5, 0.5, 1.0)
      ..translate(1000.0, 100.0, 0.0);

    builder.pushTransform(matrix4.storage);

    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// Platform view with opacity.
class PlatformViewOpacityScenario extends PlatformViewScenario {
  /// Constructs a platform view with transform scenario.
  PlatformViewOpacityScenario(Window window, String text, { int id = 0 })
      : super(window, text, id: id);

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);
    builder.pushOpacity(150);

    finishBuilderByAddingPlatformViewAndPicture(builder, id);
  }
}

/// A simple platform view for testing touch events from iOS.
class PlatformViewForTouchIOSScenario extends Scenario
    with _BasePlatformViewScenarioMixin {

  int _viewId;
  bool _accept;
  /// Creates the PlatformView scenario.
  ///
  /// The [window] parameter must not be null.
  PlatformViewForTouchIOSScenario(Window window, String text, {int id = 0, bool accept, bool rejectUntilTouchesEnded = false})
      : assert(window != null),
       _accept = accept,
      _viewId = id,
        super(window) {
    if (rejectUntilTouchesEnded) {
      createPlatformView(window, text, id, viewType: 'scenarios/textPlatformView_blockPolicyUntilTouchesEnded');
    } else {
      createPlatformView(window, text, id);
    }
  }

  @override
  void onBeginFrame(Duration duration) {
    final SceneBuilder builder = SceneBuilder();

    builder.pushOffset(0, 0);
    finishBuilderByAddingPlatformViewAndPicture(builder, _viewId);
  }

  @override
  void onPointerDataPacket(PointerDataPacket packet) {
    if (packet.data.first.change == PointerChange.add) {
    String method = 'rejectGesture';
    if (_accept) {
      method = 'acceptGesture';
    }
    const int _valueString = 7;
    const int _valueInt32 = 3;
    const int _valueMap = 13;
    final Uint8List message = Uint8List.fromList(<int>[
      _valueString,
      method.length,
      ...utf8.encode(method),
      _valueMap,
      1,
      _valueString,
      'id'.length,
      ...utf8.encode('id'),
      _valueInt32,
      ..._to32(_viewId),
    ]);
    window.sendPlatformMessage(
      'flutter/platform_views',
      message.buffer.asByteData(),
      (ByteData response) {},
    );
    }

  }
}

mixin _BasePlatformViewScenarioMixin on Scenario {
  int _textureId;

  bool get usesAndroidHybridComposition {
    return (scenarioParams['use_android_view'] as bool) == true;
  }

  /// Construct the platform view related scenario
  ///
  /// It prepare a TextPlatformView so it can be added to the SceneBuilder in `onBeginFrame`.
  /// Call this method in the constructor of the platform view related scenarios
  /// to perform necessary set up.
  void createPlatformView(Window window, String text, int id, {String viewType = 'scenarios/textPlatformView'}) {
    const int _valueTrue = 1;
    const int _valueInt32 = 3;
    const int _valueFloat64 = 6;
    const int _valueString = 7;
    const int _valueUint8List = 8;
    const int _valueMap = 13;

    final Uint8List message = Uint8List.fromList(<int>[
      _valueString,
      'create'.length, // this won't work if we use multi-byte characters.
      ...utf8.encode('create'),
      _valueMap,
      if (Platform.isIOS)
        3, // 3 entries in map for iOS.
      if (Platform.isAndroid && !usesAndroidHybridComposition)
        6, // 6 entries in map for virtual displays on Android.
      if (Platform.isAndroid && usesAndroidHybridComposition)
        5, // 5 entries in map for Android views.
      _valueString,
      'id'.length,
      ...utf8.encode('id'),
      _valueInt32,
      ..._to32(id),
      _valueString,
      'viewType'.length,
      ...utf8.encode('viewType'),
      _valueString,
      viewType.length,
      ...utf8.encode(viewType),
      if (Platform.isAndroid && !usesAndroidHybridComposition) ...<int>[
        _valueString,
        'width'.length,
        ...utf8.encode('width'),
        _valueFloat64,
        ..._to64(500.0),
        _valueString,
        'height'.length,
        ...utf8.encode('height'),
        _valueFloat64,
        ..._to64(500.0),
        _valueString,
        'direction'.length,
        ...utf8.encode('direction'),
        _valueInt32,
        ..._to32(0), // LTR
      ],
      if (Platform.isAndroid && usesAndroidHybridComposition) ...<int>[
        _valueString,
        'hybrid'.length,
        ...utf8.encode('hybrid'),
        _valueTrue,
        _valueString,
        'direction'.length,
        ...utf8.encode('direction'),
        _valueInt32,
        ..._to32(0), // LTR
      ],
      _valueString,
      'params'.length,
      ...utf8.encode('params'),
      _valueUint8List,
      text.length,
      ...utf8.encode(text),
    ]);

    window.sendPlatformMessage(
      'flutter/platform_views',
      message.buffer.asByteData(),
      (ByteData response) {
        if (response != null && Platform.isAndroid && !usesAndroidHybridComposition) {
          // Envelope.
          _textureId = response.getUint8(0);
        }
      },
    );
  }

  void _addPlatformViewtoScene(
    SceneBuilder sceneBuilder,
    int viewId,
    double width,
    double height, {
    Offset overlayOffset,
  }) {
    overlayOffset ??= const Offset(50, 50);
    if (Platform.isIOS) {
      sceneBuilder.addPlatformView(viewId, offset: overlayOffset, width: width, height: height);
    } else if (Platform.isAndroid) {
      if (usesAndroidHybridComposition) {
        // Hybrid composition does not support `offset`.
        // https://github.com/flutter/flutter/issues/60630
        sceneBuilder.pushOffset(overlayOffset.dx, overlayOffset.dy);
        sceneBuilder.addPlatformView(viewId, width: width, height: height);
        sceneBuilder.pop();
      } else if (_textureId != null) {
        sceneBuilder.addTexture(_textureId, offset: overlayOffset, width: width, height: height);
      }
    } else {
      throw UnsupportedError('Platform ${Platform.operatingSystem} is not supported');
    }
  }

  // Add a platform view and a picture to the scene, then finish the `sceneBuilder`.
  void finishBuilderByAddingPlatformViewAndPicture(
    SceneBuilder sceneBuilder,
    int viewId, {
    Offset overlayOffset,
  }) {
    overlayOffset ??= const Offset(50, 50);
    _addPlatformViewtoScene(
      sceneBuilder,
      viewId,
      500,
      500,
      overlayOffset: overlayOffset,
    );
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    canvas.drawCircle(
      overlayOffset,
      50,
      Paint()..color = const Color(0xFFABCDEF),
    );
    final Picture picture = recorder.endRecording();
    sceneBuilder.addPicture(const Offset(300, 300), picture);
    final Scene scene = sceneBuilder.build();
    window.render(scene);
    scene.dispose();
  }
}
