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

#include <Metal/Metal.h>
#import <UIKit/UIGestureRecognizerSubclass.h>

#include <list>
#include <map>
#include <memory>
#include <string>

#include "flutter/common/graphics/persistent_cache.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlayView.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/ios/ios_surface.h"

@implementation UIView (FirstResponder)
- (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
  if (self.isFirstResponder) {
    return YES;
  }
  for (UIView* subview in self.subviews) {
    if (subview.flt_hasFirstResponderInViewHierarchySubtree) {
      return YES;
    }
  }
  return NO;
}
@end

// Determines if the `clip_rect` from a clipRect mutator contains the
// `platformview_boundingrect`.
//
// `clip_rect` is in its own coordinate space. The rect needs to be transformed by
// `transform_matrix` to be in the coordinate space where the PlatformView is displayed.
//
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
// space where the PlatformView is displayed.
static bool ClipRectContainsPlatformViewBoundingRect(const SkRect& clip_rect,
                                                     const SkRect& platformview_boundingrect,
                                                     const SkMatrix& transform_matrix) {
  SkRect transformed_rect = transform_matrix.mapRect(clip_rect);
  return transformed_rect.contains(platformview_boundingrect);
}

// Determines if the `clipRRect` from a clipRRect mutator contains the
// `platformview_boundingrect`.
//
// `clip_rrect` is in its own coordinate space. The rrect needs to be transformed by
// `transform_matrix` to be in the coordinate space where the PlatformView is displayed.
//
// `platformview_boundingrect` is the final bounding rect of the PlatformView in the coordinate
// space where the PlatformView is displayed.
static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
                                                      const SkRect& platformview_boundingrect,
                                                      const SkMatrix& transform_matrix) {
  SkVector upper_left = clip_rrect.radii(SkRRect::Corner::kUpperLeft_Corner);
  SkVector upper_right = clip_rrect.radii(SkRRect::Corner::kUpperRight_Corner);
  SkVector lower_right = clip_rrect.radii(SkRRect::Corner::kLowerRight_Corner);
  SkVector lower_left = clip_rrect.radii(SkRRect::Corner::kLowerLeft_Corner);
  SkScalar transformed_upper_left_x = transform_matrix.mapRadius(upper_left.x());
  SkScalar transformed_upper_left_y = transform_matrix.mapRadius(upper_left.y());
  SkScalar transformed_upper_right_x = transform_matrix.mapRadius(upper_right.x());
  SkScalar transformed_upper_right_y = transform_matrix.mapRadius(upper_right.y());
  SkScalar transformed_lower_right_x = transform_matrix.mapRadius(lower_right.x());
  SkScalar transformed_lower_right_y = transform_matrix.mapRadius(lower_right.y());
  SkScalar transformed_lower_left_x = transform_matrix.mapRadius(lower_left.x());
  SkScalar transformed_lower_left_y = transform_matrix.mapRadius(lower_left.y());
  SkRect transformed_clip_rect = transform_matrix.mapRect(clip_rrect.rect());
  SkRRect transformed_rrect;
  SkVector corners[] = {{transformed_upper_left_x, transformed_upper_left_y},
                        {transformed_upper_right_x, transformed_upper_right_y},
                        {transformed_lower_right_x, transformed_lower_right_y},
                        {transformed_lower_left_x, transformed_lower_left_y}};
  transformed_rrect.setRectRadii(transformed_clip_rect, corners);
  return transformed_rrect.contains(platformview_boundingrect);
}

namespace flutter {
// Becomes NO if Apple's API changes and blurred backdrop filters cannot be applied.
BOOL canApplyBlurBackdrop = YES;

std::shared_ptr<FlutterPlatformViewLayer> FlutterPlatformViewLayerPool::GetLayer(
    GrDirectContext* gr_context,
    const std::shared_ptr<IOSContext>& ios_context,
    MTLPixelFormat pixel_format) {
  if (available_layer_index_ >= layers_.size()) {
    std::shared_ptr<FlutterPlatformViewLayer> layer;
    fml::scoped_nsobject<UIView> overlay_view;
    fml::scoped_nsobject<UIView> overlay_view_wrapper;

    bool impeller_enabled = !!ios_context->GetImpellerContext();
    if (!gr_context && !impeller_enabled) {
      overlay_view.reset([[FlutterOverlayView alloc] init]);
      overlay_view_wrapper.reset([[FlutterOverlayView alloc] init]);

      auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
      std::unique_ptr<IOSSurface> ios_surface = IOSSurface::Create(ios_context, ca_layer);
      std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface();

      layer = std::make_shared<FlutterPlatformViewLayer>(
          std::move(overlay_view), std::move(overlay_view_wrapper), std::move(ios_surface),
          std::move(surface));
    } else {
      CGFloat screenScale = [UIScreen mainScreen].scale;
      overlay_view.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale
                                                               pixelFormat:pixel_format]);
      overlay_view_wrapper.reset([[FlutterOverlayView alloc] initWithContentsScale:screenScale
                                                                       pixelFormat:pixel_format]);

      auto ca_layer = fml::scoped_nsobject<CALayer>{[[overlay_view.get() layer] retain]};
      std::unique_ptr<IOSSurface> ios_surface = IOSSurface::Create(ios_context, ca_layer);
      std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface(gr_context);

      layer = std::make_shared<FlutterPlatformViewLayer>(
          std::move(overlay_view), std::move(overlay_view_wrapper), std::move(ios_surface),
          std::move(surface));
      layer->gr_context = gr_context;
    }
    // The overlay view wrapper masks the overlay view.
    // This is required to keep the backing surface size unchanged between frames.
    //
    // Otherwise, changing the size of the overlay would require a new surface,
    // which can be very expensive.
    //
    // This is the case of an animation in which the overlay size is changing in every frame.
    //
    // +------------------------+
    // |   overlay_view         |
    // |    +--------------+    |              +--------------+
    // |    |    wrapper   |    |  == mask =>  | overlay_view |
    // |    +--------------+    |              +--------------+
    // +------------------------+
    layer->overlay_view_wrapper.get().clipsToBounds = YES;
    [layer->overlay_view_wrapper.get() addSubview:layer->overlay_view];
    layers_.push_back(layer);
  }
  std::shared_ptr<FlutterPlatformViewLayer> layer = layers_[available_layer_index_];
  if (gr_context != layer->gr_context) {
    layer->gr_context = gr_context;
    // The overlay already exists, but the GrContext was changed so we need to recreate
    // the rendering surface with the new GrContext.
    IOSSurface* ios_surface = layer->ios_surface.get();
    std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface(gr_context);
    layer->surface = std::move(surface);
  }
  available_layer_index_++;
  return layer;
}

void FlutterPlatformViewLayerPool::RecycleLayers() {
  available_layer_index_ = 0;
}

std::vector<std::shared_ptr<FlutterPlatformViewLayer>>
FlutterPlatformViewLayerPool::GetUnusedLayers() {
  std::vector<std::shared_ptr<FlutterPlatformViewLayer>> results;
  for (size_t i = available_layer_index_; i < layers_.size(); i++) {
    results.push_back(layers_[i]);
  }
  return results;
}

void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) {
  flutter_view_.reset([flutter_view retain]);
}

void FlutterPlatformViewsController::SetFlutterViewController(
    UIViewController* flutter_view_controller) {
  flutter_view_controller_.reset([flutter_view_controller retain]);
}

UIViewController* FlutterPlatformViewsController::getFlutterViewController() {
  return flutter_view_controller_.get();
}

void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, FlutterResult result) {
  if ([[call method] isEqualToString:@"create"]) {
    OnCreate(call, result);
  } else if ([[call method] isEqualToString:@"dispose"]) {
    OnDispose(call, result);
  } else if ([[call method] isEqualToString:@"acceptGesture"]) {
    OnAcceptGesture(call, result);
  } else if ([[call method] isEqualToString:@"rejectGesture"]) {
    OnRejectGesture(call, result);
  } else {
    result(FlutterMethodNotImplemented);
  }
}

void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterResult result) {
  NSDictionary<NSString*, id>* args = [call arguments];

  int64_t viewId = [args[@"id"] longLongValue];
  NSString* viewTypeString = args[@"viewType"];
  std::string viewType(viewTypeString.UTF8String);

  if (views_.count(viewId) != 0) {
    result([FlutterError errorWithCode:@"recreating_view"
                               message:@"trying to create an already created view"
                               details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]);
  }

  NSObject<FlutterPlatformViewFactory>* factory = factories_[viewType].get();
  if (factory == nil) {
    result([FlutterError
        errorWithCode:@"unregistered_view_type"
              message:[NSString stringWithFormat:@"A UIKitView widget is trying to create a "
                                                 @"PlatformView with an unregistered type: < %@ >",
                                                 viewTypeString]
              details:@"If you are the author of the PlatformView, make sure `registerViewFactory` "
                      @"is invoked.\n"
                      @"See: "
                      @"https://docs.flutter.dev/development/platform-integration/"
                      @"platform-views#on-the-platform-side-1 for more details.\n"
                      @"If you are not the author of the PlatformView, make sure to call "
                      @"`GeneratedPluginRegistrant.register`."]);
    return;
  }

  id params = nil;
  if ([factory respondsToSelector:@selector(createArgsCodec)]) {
    NSObject<FlutterMessageCodec>* codec = [factory createArgsCodec];
    if (codec != nil && args[@"params"] != nil) {
      FlutterStandardTypedData* paramsData = args[@"params"];
      params = [codec decode:paramsData.data];
    }
  }

  NSObject<FlutterPlatformView>* embedded_view = [factory createWithFrame:CGRectZero
                                                           viewIdentifier:viewId
                                                                arguments:params];
  UIView* platform_view = [embedded_view view];
  // Set a unique view identifier, so the platform view can be identified in unit tests.
  platform_view.accessibilityIdentifier =
      [NSString stringWithFormat:@"platform_view[%lld]", viewId];
  views_[viewId] = fml::scoped_nsobject<NSObject<FlutterPlatformView>>([embedded_view retain]);

  FlutterTouchInterceptingView* touch_interceptor = [[[FlutterTouchInterceptingView alloc]
                  initWithEmbeddedView:platform_view
               platformViewsController:GetWeakPtr()
      gestureRecognizersBlockingPolicy:gesture_recognizers_blocking_policies_[viewType]]
      autorelease];

  touch_interceptors_[viewId] =
      fml::scoped_nsobject<FlutterTouchInterceptingView>([touch_interceptor retain]);

  ChildClippingView* clipping_view =
      [[[ChildClippingView alloc] initWithFrame:CGRectZero] autorelease];
  [clipping_view addSubview:touch_interceptor];
  root_views_[viewId] = fml::scoped_nsobject<UIView>([clipping_view retain]);

  result(nil);
}

void FlutterPlatformViewsController::OnDispose(FlutterMethodCall* call, FlutterResult result) {
  NSNumber* arg = [call arguments];
  int64_t viewId = [arg longLongValue];

  if (views_.count(viewId) == 0) {
    result([FlutterError errorWithCode:@"unknown_view"
                               message:@"trying to dispose an unknown"
                               details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]);
    return;
  }
  // We wait for next submitFrame to dispose views.
  views_to_dispose_.insert(viewId);
  result(nil);
}

void FlutterPlatformViewsController::OnAcceptGesture(FlutterMethodCall* call,
                                                     FlutterResult result) {
  NSDictionary<NSString*, id>* args = [call arguments];
  int64_t viewId = [args[@"id"] longLongValue];

  if (views_.count(viewId) == 0) {
    result([FlutterError errorWithCode:@"unknown_view"
                               message:@"trying to set gesture state for an unknown view"
                               details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]);
    return;
  }

  FlutterTouchInterceptingView* view = touch_interceptors_[viewId].get();
  [view releaseGesture];

  result(nil);
}

void FlutterPlatformViewsController::OnRejectGesture(FlutterMethodCall* call,
                                                     FlutterResult result) {
  NSDictionary<NSString*, id>* args = [call arguments];
  int64_t viewId = [args[@"id"] longLongValue];

  if (views_.count(viewId) == 0) {
    result([FlutterError errorWithCode:@"unknown_view"
                               message:@"trying to set gesture state for an unknown view"
                               details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]);
    return;
  }

  FlutterTouchInterceptingView* view = touch_interceptors_[viewId].get();
  [view blockGesture];

  result(nil);
}

void FlutterPlatformViewsController::RegisterViewFactory(
    NSObject<FlutterPlatformViewFactory>* factory,
    NSString* factoryId,
    FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy) {
  std::string idString([factoryId UTF8String]);
  FML_CHECK(factories_.count(idString) == 0);
  factories_[idString] =
      fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>([factory retain]);
  gesture_recognizers_blocking_policies_[idString] = gestureRecognizerBlockingPolicy;
}

void FlutterPlatformViewsController::BeginFrame(SkISize frame_size) {
  ResetFrameState();
  frame_size_ = frame_size;
}

void FlutterPlatformViewsController::CancelFrame() {
  ResetFrameState();
}

// TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474
// Make this method check if there are pending view operations instead.
// Also rename it to `HasPendingViewOperations`.
bool FlutterPlatformViewsController::HasPlatformViewThisOrNextFrame() {
  return !composition_order_.empty() || !active_composition_order_.empty();
}

const int FlutterPlatformViewsController::kDefaultMergedLeaseDuration;

PostPrerollResult FlutterPlatformViewsController::PostPrerollAction(
    const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
  // TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474
  // Rename `has_platform_view` to `view_mutated` when the above issue is resolved.
  if (!HasPlatformViewThisOrNextFrame()) {
    return PostPrerollResult::kSuccess;
  }
  if (!raster_thread_merger->IsMerged()) {
    // The raster thread merger may be disabled if the rasterizer is being
    // created or teared down.
    //
    // In such cases, the current frame is dropped, and a new frame is attempted
    // with the same layer tree.
    //
    // Eventually, the frame is submitted once this method returns `kSuccess`.
    // At that point, the raster tasks are handled on the platform thread.
    CancelFrame();
    return PostPrerollResult::kSkipAndRetryFrame;
  }
  // If the post preroll action is successful, we will display platform views in the current frame.
  // In order to sync the rendering of the platform views (quartz) with skia's rendering,
  // We need to begin an explicit CATransaction. This transaction needs to be submitted
  // after the current frame is submitted.
  BeginCATransaction();
  raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
  return PostPrerollResult::kSuccess;
}

void FlutterPlatformViewsController::EndFrame(
    bool should_resubmit_frame,
    const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
  if (should_resubmit_frame) {
    raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
  }
}

void FlutterPlatformViewsController::PushFilterToVisitedPlatformViews(
    const std::shared_ptr<const DlImageFilter>& filter,
    const SkRect& filter_rect) {
  for (int64_t id : visited_platform_views_) {
    EmbeddedViewParams params = current_composition_params_[id];
    params.PushImageFilter(filter, filter_rect);
    current_composition_params_[id] = params;
  }
}

void FlutterPlatformViewsController::PrerollCompositeEmbeddedView(
    int64_t view_id,
    std::unique_ptr<EmbeddedViewParams> params) {
  // All the CATransactions should be committed by the end of the last frame,
  // so catransaction_added_ must be false.
  FML_DCHECK(!catransaction_added_);

  SkRect view_bounds = SkRect::Make(frame_size_);
  std::unique_ptr<EmbedderViewSlice> view;
  view = std::make_unique<DisplayListEmbedderViewSlice>(view_bounds);
  slices_.insert_or_assign(view_id, std::move(view));

  composition_order_.push_back(view_id);

  if (current_composition_params_.count(view_id) == 1 &&
      current_composition_params_[view_id] == *params.get()) {
    // Do nothing if the params didn't change.
    return;
  }
  current_composition_params_[view_id] = EmbeddedViewParams(*params.get());
  views_to_recomposite_.insert(view_id);
}

size_t FlutterPlatformViewsController::EmbeddedViewCount() {
  return composition_order_.size();
}

UIView* FlutterPlatformViewsController::GetPlatformViewByID(int64_t view_id) {
  return [GetFlutterTouchInterceptingViewByID(view_id) embeddedView];
}

FlutterTouchInterceptingView* FlutterPlatformViewsController::GetFlutterTouchInterceptingViewByID(
    int64_t view_id) {
  if (views_.empty()) {
    return nil;
  }
  return touch_interceptors_[view_id].get();
}

long FlutterPlatformViewsController::FindFirstResponderPlatformViewId() {
  for (auto const& [id, root_view] : root_views_) {
    if ((UIView*)(root_view.get()).flt_hasFirstResponderInViewHierarchySubtree) {
      return id;
    }
  }
  return -1;
}

int FlutterPlatformViewsController::CountClips(const MutatorsStack& mutators_stack) {
  std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator iter = mutators_stack.Bottom();
  int clipCount = 0;
  while (iter != mutators_stack.Top()) {
    if ((*iter)->IsClipType()) {
      clipCount++;
    }
    ++iter;
  }
  return clipCount;
}

void FlutterPlatformViewsController::ClipViewSetMaskView(UIView* clipView) {
  if (clipView.maskView) {
    return;
  }
  UIView* flutterView = flutter_view_.get();
  CGRect frame =
      CGRectMake(-clipView.frame.origin.x, -clipView.frame.origin.y,
                 CGRectGetWidth(flutterView.bounds), CGRectGetHeight(flutterView.bounds));
  clipView.maskView = [mask_view_pool_.get() getMaskViewWithFrame:frame];
}

// This method is only called when the `embedded_view` needs to be re-composited at the current
// frame. See: `CompositeWithParams` for details.
void FlutterPlatformViewsController::ApplyMutators(const MutatorsStack& mutators_stack,
                                                   UIView* embedded_view,
                                                   const SkRect& bounding_rect) {
  if (flutter_view_ == nullptr) {
    return;
  }
  FML_DCHECK(CATransform3DEqualToTransform(embedded_view.layer.transform, CATransform3DIdentity));
  ResetAnchor(embedded_view.layer);
  ChildClippingView* clipView = (ChildClippingView*)embedded_view.superview;

  SkMatrix transformMatrix;
  NSMutableArray* blurFilters = [[[NSMutableArray alloc] init] autorelease];
  FML_DCHECK(!clipView.maskView ||
             [clipView.maskView isKindOfClass:[FlutterClippingMaskView class]]);
  if (clipView.maskView) {
    [mask_view_pool_.get() insertViewToPoolIfNeeded:(FlutterClippingMaskView*)(clipView.maskView)];
    clipView.maskView = nil;
  }
  CGFloat screenScale = [UIScreen mainScreen].scale;
  auto iter = mutators_stack.Begin();
  while (iter != mutators_stack.End()) {
    switch ((*iter)->GetType()) {
      case kTransform: {
        transformMatrix.preConcat((*iter)->GetMatrix());
        break;
      }
      case kClipRect: {
        if (ClipRectContainsPlatformViewBoundingRect((*iter)->GetRect(), bounding_rect,
                                                     transformMatrix)) {
          break;
        }
        ClipViewSetMaskView(clipView);
        [(FlutterClippingMaskView*)clipView.maskView clipRect:(*iter)->GetRect()
                                                       matrix:transformMatrix];
        break;
      }
      case kClipRRect: {
        if (ClipRRectContainsPlatformViewBoundingRect((*iter)->GetRRect(), bounding_rect,
                                                      transformMatrix)) {
          break;
        }
        ClipViewSetMaskView(clipView);
        [(FlutterClippingMaskView*)clipView.maskView clipRRect:(*iter)->GetRRect()
                                                        matrix:transformMatrix];
        break;
      }
      case kClipPath: {
        // TODO(cyanglaz): Find a way to pre-determine if path contains the PlatformView boudning
        // rect. See `ClipRRectContainsPlatformViewBoundingRect`.
        // https://github.com/flutter/flutter/issues/118650
        ClipViewSetMaskView(clipView);
        [(FlutterClippingMaskView*)clipView.maskView clipPath:(*iter)->GetPath()
                                                       matrix:transformMatrix];
        break;
      }
      case kOpacity:
        embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha;
        break;
      case kBackdropFilter: {
        // Only support DlBlurImageFilter for BackdropFilter.
        if (!canApplyBlurBackdrop || !(*iter)->GetFilterMutation().GetFilter().asBlur()) {
          break;
        }
        CGRect filterRect =
            flutter::GetCGRectFromSkRect((*iter)->GetFilterMutation().GetFilterRect());
        // `filterRect` is in global coordinates. We need to convert to local space.
        filterRect = CGRectApplyAffineTransform(
            filterRect, CGAffineTransformMakeScale(1 / screenScale, 1 / screenScale));
        // `filterRect` reprents the rect that should be filtered inside the `flutter_view_`.
        // The `PlatformViewFilter` needs the frame inside the `clipView` that needs to be
        // filtered.
        if (CGRectIsNull(CGRectIntersection(filterRect, clipView.frame))) {
          break;
        }
        CGRect intersection = CGRectIntersection(filterRect, clipView.frame);
        CGRect frameInClipView = [flutter_view_.get() convertRect:intersection toView:clipView];
        // sigma_x is arbitrarily chosen as the radius value because Quartz sets
        // sigma_x and sigma_y equal to each other. DlBlurImageFilter's Tile Mode
        // is not supported in Quartz's gaussianBlur CAFilter, so it is not used
        // to blur the PlatformView.
        CGFloat blurRadius = (*iter)->GetFilterMutation().GetFilter().asBlur()->sigma_x();
        UIVisualEffectView* visualEffectView = [[[UIVisualEffectView alloc]
            initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]] autorelease];
        PlatformViewFilter* filter =
            [[[PlatformViewFilter alloc] initWithFrame:frameInClipView
                                            blurRadius:blurRadius
                                      visualEffectView:visualEffectView] autorelease];
        if (!filter) {
          canApplyBlurBackdrop = NO;
        } else {
          [blurFilters addObject:filter];
        }
        break;
      }
    }
    ++iter;
  }

  if (canApplyBlurBackdrop) {
    [clipView applyBlurBackdropFilters:blurFilters];
  }

  // The UIKit frame is set based on the logical resolution (points) instead of physical.
  // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html).
  // However, flow is based on the physical resolution. For example, 1000 pixels in flow equals
  // 500 points in UIKit for devices that has screenScale of 2. We need to scale the transformMatrix
  // down to the logical resoltion before applying it to the layer of PlatformView.
  transformMatrix.postScale(1 / screenScale, 1 / screenScale);

  // Reverse the offset of the clipView.
  // The clipView's frame includes the final translate of the final transform matrix.
  // Thus, this translate needs to be reversed so the platform view can layout at the correct
  // offset.
  //
  // Note that the transforms are not applied to the clipping paths because clipping paths happen on
  // the mask view, whose origin is always (0,0) to the flutter_view.
  transformMatrix.postTranslate(-clipView.frame.origin.x, -clipView.frame.origin.y);

  embedded_view.layer.transform = flutter::GetCATransform3DFromSkMatrix(transformMatrix);
}

// Composite the PlatformView with `view_id`.
//
// Every frame, during the paint traversal of the layer tree, this method is called for all
// the PlatformViews in `views_to_recomposite_`.
//
// Note that `views_to_recomposite_` does not represent all the views in the view hierarchy,
// if a PlatformView does not change its composition parameter from last frame, it is not
// included in the `views_to_recomposite_`.
void FlutterPlatformViewsController::CompositeWithParams(int64_t view_id,
                                                         const EmbeddedViewParams& params) {
  CGRect frame = CGRectMake(0, 0, params.sizePoints().width(), params.sizePoints().height());
  FlutterTouchInterceptingView* touchInterceptor = touch_interceptors_[view_id].get();
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
  FML_DCHECK(CGPointEqualToPoint([touchInterceptor embeddedView].frame.origin, CGPointZero));
  if (non_zero_origin_views_.find(view_id) == non_zero_origin_views_.end() &&
      !CGPointEqualToPoint([touchInterceptor embeddedView].frame.origin, CGPointZero)) {
    non_zero_origin_views_.insert(view_id);
    NSLog(
        @"A Embedded PlatformView's origin is not CGPointZero.\n"
         "  View id: %@\n"
         "  View info: \n %@ \n"
         "A non-zero origin might cause undefined behavior.\n"
         "See https://github.com/flutter/flutter/issues/109700 for more details.\n"
         "If you are the author of the PlatformView, please update the implementation of the "
         "PlatformView to have a (0, 0) origin.\n"
         "If you have a valid case of using a non-zero origin, "
         "please leave a comment at https://github.com/flutter/flutter/issues/109700 with details.",
        @(view_id), [touchInterceptor embeddedView]);
  }
#endif
  touchInterceptor.layer.transform = CATransform3DIdentity;
  touchInterceptor.frame = frame;
  touchInterceptor.alpha = 1;

  const MutatorsStack& mutatorStack = params.mutatorsStack();
  UIView* clippingView = root_views_[view_id].get();
  // The frame of the clipping view should be the final bounding rect.
  // Because the translate matrix in the Mutator Stack also includes the offset,
  // when we apply the transforms matrix in |ApplyMutators|, we need
  // to remember to do a reverse translate.
  const SkRect& rect = params.finalBoundingRect();
  CGFloat screenScale = [UIScreen mainScreen].scale;
  clippingView.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale,
                                  rect.width() / screenScale, rect.height() / screenScale);
  ApplyMutators(mutatorStack, touchInterceptor, rect);
}

DlCanvas* FlutterPlatformViewsController::CompositeEmbeddedView(int64_t view_id) {
  // Any UIKit related code has to run on main thread.
  FML_DCHECK([[NSThread currentThread] isMainThread]);
  // Do nothing if the view doesn't need to be composited.
  if (views_to_recomposite_.count(view_id) == 0) {
    return slices_[view_id]->canvas();
  }
  CompositeWithParams(view_id, current_composition_params_[view_id]);
  views_to_recomposite_.erase(view_id);
  return slices_[view_id]->canvas();
}

void FlutterPlatformViewsController::Reset() {
  for (int64_t view_id : active_composition_order_) {
    UIView* sub_view = root_views_[view_id].get();
    [sub_view removeFromSuperview];
  }
  root_views_.clear();
  touch_interceptors_.clear();
  views_.clear();
  composition_order_.clear();
  active_composition_order_.clear();
  slices_.clear();
  current_composition_params_.clear();
  clip_count_.clear();
  views_to_recomposite_.clear();
  layer_pool_->RecycleLayers();
  visited_platform_views_.clear();
}

SkRect FlutterPlatformViewsController::GetPlatformViewRect(int64_t view_id) {
  UIView* platform_view = GetPlatformViewByID(view_id);
  UIScreen* screen = [UIScreen mainScreen];
  CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds
                                                    toView:flutter_view_];
  return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale,    //
                          platform_view_cgrect.origin.y * screen.scale,    //
                          platform_view_cgrect.size.width * screen.scale,  //
                          platform_view_cgrect.size.height * screen.scale  //
  );
}

bool FlutterPlatformViewsController::SubmitFrame(GrDirectContext* gr_context,
                                                 const std::shared_ptr<IOSContext>& ios_context,
                                                 std::unique_ptr<SurfaceFrame> frame) {
  TRACE_EVENT0("flutter", "FlutterPlatformViewsController::SubmitFrame");

  // Any UIKit related code has to run on main thread.
  FML_DCHECK([[NSThread currentThread] isMainThread]);
  if (flutter_view_ == nullptr) {
    return frame->Submit();
  }

  DisposeViews();

  DlCanvas* background_canvas = frame->Canvas();

  // Resolve all pending GPU operations before allocating a new surface.
  background_canvas->Flush();

  // Clipping the background canvas before drawing the picture recorders requires
  // saving and restoring the clip context.
  DlAutoCanvasRestore save(background_canvas, /*do_save=*/true);

  // Maps a platform view id to a vector of `FlutterPlatformViewLayer`.
  LayersMap platform_view_layers;

  auto did_submit = true;
  auto num_platform_views = composition_order_.size();

  // TODO(hellohuanlin) this double for-loop is expensive with wasted computations.
  // See: https://github.com/flutter/flutter/issues/145802
  for (size_t i = 0; i < num_platform_views; i++) {
    int64_t platform_view_id = composition_order_[i];
    EmbedderViewSlice* slice = slices_[platform_view_id].get();
    slice->end_recording();

    // Check if the current picture contains overlays that intersect with the
    // current platform view or any of the previous platform views.
    for (size_t j = i + 1; j > 0; j--) {
      int64_t current_platform_view_id = composition_order_[j - 1];
      SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
      std::vector<SkIRect> intersection_rects = slice->region(platform_view_rect).getRects();
      const SkIRect rounded_in_platform_view_rect = platform_view_rect.roundIn();
      // Ignore intersections of single width/height on the edge of the platform view.
      // This is to address the following performance issue when interleaving adjacent
      // platform views and layers:
      // Since we `roundOut` both platform view rects and the layer rects, as long as
      // the coordinate is fractional, there will be an intersection of a single pixel width
      // (or height) after rounding out, even if they do not intersect before rounding out.
      // We have to round out both platform view rect and the layer rect.
      // Rounding in platform view rect will result in missing pixel on the intersection edge.
      // Rounding in layer rect will result in missing pixel on the edge of the layer on top
      // of the platform view.
      for (auto it = intersection_rects.begin(); it != intersection_rects.end(); /*no-op*/) {
        // If intersection_rect does not intersect with the *rounded in* platform
        // view rect, then the intersection must be a single pixel width (or height) on edge.
        if (!SkIRect::Intersects(*it, rounded_in_platform_view_rect)) {
          it = intersection_rects.erase(it);
        } else {
          ++it;
        }
      }

      auto allocation_size = intersection_rects.size();

      // For testing purposes, the overlay id is used to find the overlay view.
      // This is the index of the layer for the current platform view.
      auto overlay_id = platform_view_layers[current_platform_view_id].size();

      // If the max number of allocations per platform view is exceeded,
      // then join all the rects into a single one.
      //
      // TODO(egarciad): Consider making this configurable.
      // https://github.com/flutter/flutter/issues/52510
      if (allocation_size > kMaxLayerAllocations) {
        SkIRect joined_rect = SkIRect::MakeEmpty();
        for (const SkIRect& rect : intersection_rects) {
          joined_rect.join(rect);
        }
        // Replace the rects in the intersection rects list for a single rect that is
        // the union of all the rects in the list.
        intersection_rects.clear();
        intersection_rects.push_back(joined_rect);
      }
      for (SkIRect& joined_rect : intersection_rects) {
        // Get the intersection rect between the current rect
        // and the platform view rect.
        joined_rect.intersect(platform_view_rect.roundOut());
        // Clip the background canvas, so it doesn't contain any of the pixels drawn
        // on the overlay layer.
        background_canvas->ClipRect(SkRect::Make(joined_rect), DlCanvas::ClipOp::kDifference);
        // Get a new host layer.
        std::shared_ptr<FlutterPlatformViewLayer> layer =
            GetLayer(gr_context,                                      //
                     ios_context,                                     //
                     slice,                                           //
                     joined_rect,                                     //
                     current_platform_view_id,                        //
                     overlay_id,                                      //
                     ((FlutterView*)flutter_view_.get()).pixelFormat  //
            );
        did_submit &= layer->did_submit_last_frame;
        platform_view_layers[current_platform_view_id].push_back(layer);
        overlay_id++;
      }
    }
    slice->render_into(background_canvas);
  }

  // Manually trigger the SkAutoCanvasRestore before we submit the frame
  save.Restore();

  // If a layer was allocated in the previous frame, but it's not used in the current frame,
  // then it can be removed from the scene.
  RemoveUnusedLayers();
  // Organize the layers by their z indexes.
  BringLayersIntoView(platform_view_layers);
  // Mark all layers as available, so they can be used in the next frame.
  layer_pool_->RecycleLayers();

  did_submit &= frame->Submit();

  // If the frame is submitted with embedded platform views,
  // there should be a |[CATransaction begin]| call in this frame prior to all the drawing.
  // If that case, we need to commit the transaction.
  CommitCATransactionIfNeeded();
  return did_submit;
}

void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) {
  FML_DCHECK(flutter_view_);
  UIView* flutter_view = flutter_view_.get();
  // Clear the `active_composition_order_`, which will be populated down below.
  active_composition_order_.clear();
  NSMutableArray* desired_platform_subviews = [NSMutableArray array];
  for (size_t i = 0; i < composition_order_.size(); i++) {
    int64_t platform_view_id = composition_order_[i];
    std::vector<std::shared_ptr<FlutterPlatformViewLayer>> layers = layer_map[platform_view_id];
    UIView* platform_view_root = root_views_[platform_view_id].get();
    [desired_platform_subviews addObject:platform_view_root];
    for (const std::shared_ptr<FlutterPlatformViewLayer>& layer : layers) {
      [desired_platform_subviews addObject:layer->overlay_view_wrapper];
    }
    active_composition_order_.push_back(platform_view_id);
  }

  NSSet* desired_platform_subviews_set = [NSSet setWithArray:desired_platform_subviews];
  NSArray* existing_platform_subviews = [flutter_view.subviews
      filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object,
                                                                        NSDictionary* bindings) {
        return [desired_platform_subviews_set containsObject:object];
      }]];
  // Manipulate view hierarchy only if needed, to address a performance issue where
  // `BringLayersIntoView` is called even when view hierarchy stays the same.
  // See: https://github.com/flutter/flutter/issues/121833
  // TODO(hellohuanlin): investigate if it is possible to skip unnecessary BringLayersIntoView.
  if (![desired_platform_subviews isEqualToArray:existing_platform_subviews]) {
    for (UIView* subview in desired_platform_subviews) {
      // `addSubview` will automatically reorder subview if it is already added.
      [flutter_view addSubview:subview];
    }
  }
}

std::shared_ptr<FlutterPlatformViewLayer> FlutterPlatformViewsController::GetLayer(
    GrDirectContext* gr_context,
    const std::shared_ptr<IOSContext>& ios_context,
    EmbedderViewSlice* slice,
    SkIRect rect,
    int64_t view_id,
    int64_t overlay_id,
    MTLPixelFormat pixel_format) {
  FML_DCHECK(flutter_view_);
  std::shared_ptr<FlutterPlatformViewLayer> layer =
      layer_pool_->GetLayer(gr_context, ios_context, pixel_format);

  UIView* overlay_view_wrapper = layer->overlay_view_wrapper.get();
  auto screenScale = [UIScreen mainScreen].scale;
  // Set the size of the overlay view wrapper.
  // This wrapper view masks the overlay view.
  overlay_view_wrapper.frame = CGRectMake(rect.x() / screenScale, rect.y() / screenScale,
                                          rect.width() / screenScale, rect.height() / screenScale);
  // Set a unique view identifier, so the overlay_view_wrapper can be identified in XCUITests.
  overlay_view_wrapper.accessibilityIdentifier =
      [NSString stringWithFormat:@"platform_view[%lld].overlay[%lld]", view_id, overlay_id];

  UIView* overlay_view = layer->overlay_view.get();
  // Set the size of the overlay view.
  // This size is equal to the device screen size.
  overlay_view.frame = [flutter_view_.get() convertRect:flutter_view_.get().bounds
                                                 toView:overlay_view_wrapper];
  // Set a unique view identifier, so the overlay_view can be identified in XCUITests.
  overlay_view.accessibilityIdentifier =
      [NSString stringWithFormat:@"platform_view[%lld].overlay_view[%lld]", view_id, overlay_id];

  std::unique_ptr<SurfaceFrame> frame = layer->surface->AcquireFrame(frame_size_);
  // If frame is null, AcquireFrame already printed out an error message.
  if (!frame) {
    return layer;
  }
  DlCanvas* overlay_canvas = frame->Canvas();
  int restore_count = overlay_canvas->GetSaveCount();
  overlay_canvas->Save();
  overlay_canvas->ClipRect(SkRect::Make(rect));
  overlay_canvas->Clear(DlColor::kTransparent());
  slice->render_into(overlay_canvas);
  overlay_canvas->RestoreToCount(restore_count);

  layer->did_submit_last_frame = frame->Submit();
  return layer;
}

void FlutterPlatformViewsController::RemoveUnusedLayers() {
  std::vector<std::shared_ptr<FlutterPlatformViewLayer>> layers = layer_pool_->GetUnusedLayers();
  for (const std::shared_ptr<FlutterPlatformViewLayer>& layer : layers) {
    [layer->overlay_view_wrapper removeFromSuperview];
  }

  std::unordered_set<int64_t> composition_order_set;
  for (int64_t view_id : composition_order_) {
    composition_order_set.insert(view_id);
  }
  // Remove unused platform views.
  for (int64_t view_id : active_composition_order_) {
    if (composition_order_set.find(view_id) == composition_order_set.end()) {
      UIView* platform_view_root = root_views_[view_id].get();
      [platform_view_root removeFromSuperview];
    }
  }
}

void FlutterPlatformViewsController::DisposeViews() {
  if (views_to_dispose_.empty()) {
    return;
  }

  FML_DCHECK([[NSThread currentThread] isMainThread]);

  std::unordered_set<int64_t> views_to_composite(composition_order_.begin(),
                                                 composition_order_.end());
  std::unordered_set<int64_t> views_to_delay_dispose;
  for (int64_t viewId : views_to_dispose_) {
    if (views_to_composite.count(viewId)) {
      views_to_delay_dispose.insert(viewId);
      continue;
    }
    UIView* root_view = root_views_[viewId].get();
    [root_view removeFromSuperview];
    views_.erase(viewId);
    touch_interceptors_.erase(viewId);
    root_views_.erase(viewId);
    current_composition_params_.erase(viewId);
    clip_count_.erase(viewId);
    views_to_recomposite_.erase(viewId);
  }

  views_to_dispose_ = std::move(views_to_delay_dispose);
}

void FlutterPlatformViewsController::BeginCATransaction() {
  FML_DCHECK([[NSThread currentThread] isMainThread]);
  FML_DCHECK(!catransaction_added_);
  [CATransaction begin];
  catransaction_added_ = true;
}

void FlutterPlatformViewsController::CommitCATransactionIfNeeded() {
  if (catransaction_added_) {
    FML_DCHECK([[NSThread currentThread] isMainThread]);
    [CATransaction commit];
    catransaction_added_ = false;
  }
}

void FlutterPlatformViewsController::ResetFrameState() {
  slices_.clear();
  composition_order_.clear();
  visited_platform_views_.clear();
}

}  // namespace flutter

// This recognizers delays touch events from being dispatched to the responder chain until it failed
// recognizing a gesture.
//
// We only fail this recognizer when asked to do so by the Flutter framework (which does so by
// invoking an acceptGesture method on the platform_views channel). And this is how we allow the
// Flutter framework to delay or prevent the embedded view from getting a touch sequence.
@interface DelayingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>

// Indicates that if the `DelayingGestureRecognizer`'s state should be set to
// `UIGestureRecognizerStateEnded` during next `touchesEnded` call.
@property(nonatomic) bool shouldEndInNextTouchesEnded;

// Indicates that the `DelayingGestureRecognizer`'s `touchesEnded` has been invoked without
// setting the state to `UIGestureRecognizerStateEnded`.
@property(nonatomic) bool touchedEndedWithoutBlocking;

- (instancetype)initWithTarget:(id)target
                        action:(SEL)action
          forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer;
@end

// While the DelayingGestureRecognizer is preventing touches from hitting the responder chain
// the touch events are not arriving to the FlutterView (and thus not arriving to the Flutter
// framework). We use this gesture recognizer to dispatch the events directly to the FlutterView
// while during this phase.
//
// If the Flutter framework decides to dispatch events to the embedded view, we fail the
// DelayingGestureRecognizer which sends the events up the responder chain. But since the events
// are handled by the embedded view they are not delivered to the Flutter framework in this phase
// as well. So during this phase as well the ForwardingGestureRecognizer dispatched the events
// directly to the FlutterView.
@interface ForwardingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
- (instancetype)initWithTarget:(id)target
       platformViewsController:
           (fml::WeakPtr<flutter::FlutterPlatformViewsController>)platformViewsController;
@end

@implementation FlutterTouchInterceptingView {
  fml::scoped_nsobject<DelayingGestureRecognizer> _delayingRecognizer;
  FlutterPlatformViewGestureRecognizersBlockingPolicy _blockingPolicy;
  UIView* _embeddedView;
  // The used as the accessiblityContainer.
  // The `accessiblityContainer` is used in UIKit to determine the parent of this accessibility
  // node.
  NSObject* _flutterAccessibilityContainer;
}
- (instancetype)initWithEmbeddedView:(UIView*)embeddedView
             platformViewsController:
                 (fml::WeakPtr<flutter::FlutterPlatformViewsController>)platformViewsController
    gestureRecognizersBlockingPolicy:
        (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy {
  self = [super initWithFrame:embeddedView.frame];
  if (self) {
    self.multipleTouchEnabled = YES;
    _embeddedView = embeddedView;
    embeddedView.autoresizingMask =
        (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);

    [self addSubview:embeddedView];

    ForwardingGestureRecognizer* forwardingRecognizer = [[[ForwardingGestureRecognizer alloc]
                 initWithTarget:self
        platformViewsController:std::move(platformViewsController)] autorelease];

    _delayingRecognizer.reset([[DelayingGestureRecognizer alloc]
              initWithTarget:self
                      action:nil
        forwardingRecognizer:forwardingRecognizer]);
    _blockingPolicy = blockingPolicy;

    [self addGestureRecognizer:_delayingRecognizer.get()];
    [self addGestureRecognizer:forwardingRecognizer];
  }
  return self;
}

- (UIView*)embeddedView {
  return [[_embeddedView retain] autorelease];
}

- (void)releaseGesture {
  _delayingRecognizer.get().state = UIGestureRecognizerStateFailed;
}

- (void)blockGesture {
  switch (_blockingPolicy) {
    case FlutterPlatformViewGestureRecognizersBlockingPolicyEager:
      // We block all other gesture recognizers immediately in this policy.
      _delayingRecognizer.get().state = UIGestureRecognizerStateEnded;
      break;
    case FlutterPlatformViewGestureRecognizersBlockingPolicyWaitUntilTouchesEnded:
      if (_delayingRecognizer.get().touchedEndedWithoutBlocking) {
        // If touchesEnded of the `DelayingGesureRecognizer` has been already invoked,
        // we want to set the state of the `DelayingGesureRecognizer` to
        // `UIGestureRecognizerStateEnded` as soon as possible.
        _delayingRecognizer.get().state = UIGestureRecognizerStateEnded;
      } else {
        // If touchesEnded of the `DelayingGesureRecognizer` has not been invoked,
        // We will set a flag to notify the `DelayingGesureRecognizer` to set the state to
        // `UIGestureRecognizerStateEnded` when touchesEnded is called.
        _delayingRecognizer.get().shouldEndInNextTouchesEnded = YES;
      }
      break;
    default:
      break;
  }
}

// We want the intercepting view to consume the touches and not pass the touches up to the parent
// view. Make the touch event method not call super will not pass the touches up to the parent view.
// Hence we overide the touch event methods and do nothing.
- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesMoved:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
}

- (void)setFlutterAccessibilityContainer:(NSObject*)flutterAccessibilityContainer {
  _flutterAccessibilityContainer = flutterAccessibilityContainer;
}

- (id)accessibilityContainer {
  return _flutterAccessibilityContainer;
}

@end

@implementation DelayingGestureRecognizer {
  fml::scoped_nsobject<UIGestureRecognizer> _forwardingRecognizer;
}

- (instancetype)initWithTarget:(id)target
                        action:(SEL)action
          forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer {
  self = [super initWithTarget:target action:action];
  if (self) {
    self.delaysTouchesBegan = YES;
    self.delaysTouchesEnded = YES;
    self.delegate = self;
    self.shouldEndInNextTouchesEnded = NO;
    self.touchedEndedWithoutBlocking = NO;
    _forwardingRecognizer.reset([forwardingRecognizer retain]);
  }
  return self;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
    shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {
  // The forwarding gesture recognizer should always get all touch events, so it should not be
  // required to fail by any other gesture recognizer.
  return otherGestureRecognizer != _forwardingRecognizer.get() && otherGestureRecognizer != self;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
    shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer {
  return otherGestureRecognizer == self;
}

- (void)touchesBegan:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
  self.touchedEndedWithoutBlocking = NO;
  [super touchesBegan:touches withEvent:event];
}

- (void)touchesEnded:(NSSet<UITouch*>*)touches withEvent:(UIEvent*)event {
  if (self.shouldEndInNextTouchesEnded) {
    self.state = UIGestureRecognizerStateEnded;
    self.shouldEndInNextTouchesEnded = NO;
  } else {
    self.touchedEndedWithoutBlocking = YES;
  }
  [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
  self.state = UIGestureRecognizerStateFailed;
}
@end

@implementation ForwardingGestureRecognizer {
  // Weak reference to FlutterPlatformViewsController. The FlutterPlatformViewsController has
  // a reference to the FlutterViewController, where we can dispatch pointer events to.
  //
  // The lifecycle of FlutterPlatformViewsController is bind to FlutterEngine, which should always
  // outlives the FlutterViewController. And ForwardingGestureRecognizer is owned by a subview of
  // FlutterView, so the ForwardingGestureRecognizer never out lives FlutterViewController.
  // Therefore, `_platformViewsController` should never be nullptr.
  fml::WeakPtr<flutter::FlutterPlatformViewsController> _platformViewsController;
  // Counting the pointers that has started in one touch sequence.
  NSInteger _currentTouchPointersCount;
  // We can't dispatch events to the framework without this back pointer.
  // This gesture recognizer retains the `FlutterViewController` until the
  // end of a gesture sequence, that is all the touches in touchesBegan are concluded
  // with |touchesCancelled| or |touchesEnded|.
  fml::scoped_nsobject<UIViewController> _flutterViewController;
}

- (instancetype)initWithTarget:(id)target
       platformViewsController:
           (fml::WeakPtr<flutter::FlutterPlatformViewsController>)platformViewsController {
  self = [super initWithTarget:target action:nil];
  if (self) {
    self.delegate = self;
    FML_DCHECK(platformViewsController.get() != nullptr);
    _platformViewsController = std::move(platformViewsController);
    _currentTouchPointersCount = 0;
  }
  return self;
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
  FML_DCHECK(_currentTouchPointersCount >= 0);
  if (_currentTouchPointersCount == 0) {
    // At the start of each gesture sequence, we reset the `_flutterViewController`,
    // so that all the touch events in the same sequence are forwarded to the same
    // `_flutterViewController`.
    _flutterViewController.reset([_platformViewsController->getFlutterViewController() retain]);
  }
  [_flutterViewController.get() touchesBegan:touches withEvent:event];
  _currentTouchPointersCount += touches.count;
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
  [_flutterViewController.get() touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
  [_flutterViewController.get() touchesEnded:touches withEvent:event];
  _currentTouchPointersCount -= touches.count;
  // Touches in one touch sequence are sent to the touchesEnded method separately if different
  // fingers stop touching the screen at different time. So one touchesEnded method triggering does
  // not necessarially mean the touch sequence has ended. We Only set the state to
  // UIGestureRecognizerStateFailed when all the touches in the current touch sequence is ended.
  if (_currentTouchPointersCount == 0) {
    self.state = UIGestureRecognizerStateFailed;
    _flutterViewController.reset(nil);
  }
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
  // In the event of platform view is removed, iOS generates a "stationary" change type instead of
  // "cancelled" change type.
  // Flutter needs all the cancelled touches to be "cancelled" change types in order to correctly
  // handle gesture sequence.
  // We always override the change type to "cancelled".
  [((FlutterViewController*)_flutterViewController.get()) forceTouchesCancelled:touches];
  _currentTouchPointersCount -= touches.count;
  if (_currentTouchPointersCount == 0) {
    self.state = UIGestureRecognizerStateFailed;
    _flutterViewController.reset(nil);
  }
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
    shouldRecognizeSimultaneouslyWithGestureRecognizer:
        (UIGestureRecognizer*)otherGestureRecognizer {
  return YES;
}
@end
