// 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 "FLTImagePickerPlugin.h"
#import "FLTImagePickerPlugin_Test.h"

#import <AVFoundation/AVFoundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <Photos/Photos.h>
#import <PhotosUI/PHPhotoLibrary+PhotosUISupport.h>
#import <PhotosUI/PhotosUI.h>
#import <UIKit/UIKit.h>

#import "FLTImagePickerImageUtil.h"
#import "FLTImagePickerMetaDataUtil.h"
#import "FLTImagePickerPhotoAssetUtil.h"
#import "FLTPHPickerSaveImageToPathOperation.h"
#import "messages.g.h"

@implementation FLTImagePickerMethodCallContext
- (instancetype)initWithResult:(nonnull FlutterResultAdapter)result {
  if (self = [super init]) {
    _result = [result copy];
  }
  return self;
}
@end

#pragma mark -

@interface FLTImagePickerPlugin () <UINavigationControllerDelegate,
                                    UIImagePickerControllerDelegate,
                                    PHPickerViewControllerDelegate,
                                    UIAdaptivePresentationControllerDelegate>

/**
 * The PHPickerViewController instance used to pick multiple
 * images.
 */
@property(strong, nonatomic) PHPickerViewController *pickerViewController API_AVAILABLE(ios(14));

/**
 * The UIImagePickerController instances that will be used when a new
 * controller would normally be created. Each call to
 * createImagePickerController will remove the current first element from
 * the array.
 */
@property(strong, nonatomic)
    NSMutableArray<UIImagePickerController *> *imagePickerControllerOverrides;

@end

typedef NS_ENUM(NSInteger, ImagePickerClassType) { UIImagePickerClassType, PHPickerClassType };

@implementation FLTImagePickerPlugin

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
  FLTImagePickerPlugin *instance = [FLTImagePickerPlugin new];
  FLTImagePickerApiSetup(registrar.messenger, instance);
}

- (UIImagePickerController *)createImagePickerController {
  if ([self.imagePickerControllerOverrides count] > 0) {
    UIImagePickerController *controller = [self.imagePickerControllerOverrides firstObject];
    [self.imagePickerControllerOverrides removeObjectAtIndex:0];
    return controller;
  }

  return [[UIImagePickerController alloc] init];
}

- (void)setImagePickerControllerOverrides:
    (NSArray<UIImagePickerController *> *)imagePickerControllers {
  _imagePickerControllerOverrides = [imagePickerControllers mutableCopy];
}

- (UIViewController *)viewControllerWithWindow:(UIWindow *)window {
  UIWindow *windowToUse = window;
  if (windowToUse == nil) {
    for (UIWindow *window in [UIApplication sharedApplication].windows) {
      if (window.isKeyWindow) {
        windowToUse = window;
        break;
      }
    }
  }

  UIViewController *topController = windowToUse.rootViewController;
  while (topController.presentedViewController) {
    topController = topController.presentedViewController;
  }
  return topController;
}

/**
 * Returns the UIImagePickerControllerCameraDevice to use given [source].
 *
 * @param source The source specification from Dart.
 */
- (UIImagePickerControllerCameraDevice)cameraDeviceForSource:(FLTSourceSpecification *)source {
  switch (source.camera) {
    case FLTSourceCameraFront:
      return UIImagePickerControllerCameraDeviceFront;
    case FLTSourceCameraRear:
      return UIImagePickerControllerCameraDeviceRear;
  }
}

- (void)launchPHPickerWithContext:(nonnull FLTImagePickerMethodCallContext *)context
    API_AVAILABLE(ios(14)) {
  PHPickerConfiguration *config =
      [[PHPickerConfiguration alloc] initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
  config.selectionLimit = context.maxImageCount;
  config.filter = [PHPickerFilter imagesFilter];

  _pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:config];
  _pickerViewController.delegate = self;
  _pickerViewController.presentationController.delegate = self;
  self.callContext = context;

  [self checkPhotoAuthorizationForAccessLevel];
}

- (void)launchUIImagePickerWithSource:(nonnull FLTSourceSpecification *)source
                              context:(nonnull FLTImagePickerMethodCallContext *)context {
  UIImagePickerController *imagePickerController = [self createImagePickerController];
  imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
  imagePickerController.delegate = self;
  imagePickerController.mediaTypes = @[ (NSString *)kUTTypeImage ];
  self.callContext = context;

  switch (source.type) {
    case FLTSourceTypeCamera:
      [self checkCameraAuthorizationWithImagePicker:imagePickerController
                                             camera:[self cameraDeviceForSource:source]];
      break;
    case FLTSourceTypeGallery:
      [self checkPhotoAuthorizationWithImagePicker:imagePickerController];
      break;
    default:
      [self sendCallResultWithError:[FlutterError errorWithCode:@"invalid_source"
                                                        message:@"Invalid image source."
                                                        details:nil]];
      break;
  }
}

#pragma mark - FLTImagePickerApi

- (void)pickImageWithSource:(nonnull FLTSourceSpecification *)source
                    maxSize:(nonnull FLTMaxSize *)maxSize
                    quality:(nullable NSNumber *)imageQuality
                 completion:
                     (nonnull void (^)(NSString *_Nullable, FlutterError *_Nullable))completion {
  [self cancelInProgressCall];
  FLTImagePickerMethodCallContext *context = [[FLTImagePickerMethodCallContext alloc]
      initWithResult:^void(NSArray<NSString *> *paths, FlutterError *error) {
        if (paths && paths.count != 1) {
          completion(nil, [FlutterError errorWithCode:@"invalid_result"
                                              message:@"Incorrect number of return paths provided"
                                              details:nil]);
        }
        completion(paths.firstObject, error);
      }];
  context.maxSize = maxSize;
  context.imageQuality = imageQuality;
  context.maxImageCount = 1;

  if (source.type == FLTSourceTypeGallery) {  // Capture is not possible with PHPicker
    if (@available(iOS 14, *)) {
      [self launchPHPickerWithContext:context];
    } else {
      [self launchUIImagePickerWithSource:source context:context];
    }
  } else {
    [self launchUIImagePickerWithSource:source context:context];
  }
}

- (void)pickMultiImageWithMaxSize:(nonnull FLTMaxSize *)maxSize
                          quality:(nullable NSNumber *)imageQuality
                       completion:(nonnull void (^)(NSArray<NSString *> *_Nullable,
                                                    FlutterError *_Nullable))completion {
  FLTImagePickerMethodCallContext *context =
      [[FLTImagePickerMethodCallContext alloc] initWithResult:completion];
  context.maxSize = maxSize;
  context.imageQuality = imageQuality;

  if (@available(iOS 14, *)) {
    [self launchPHPickerWithContext:context];
  } else {
    // Camera is ignored for gallery mode, so the value here is arbitrary.
    [self launchUIImagePickerWithSource:[FLTSourceSpecification makeWithType:FLTSourceTypeGallery
                                                                      camera:FLTSourceCameraRear]
                                context:context];
  }
}

- (void)pickVideoWithSource:(nonnull FLTSourceSpecification *)source
                maxDuration:(nullable NSNumber *)maxDurationSeconds
                 completion:
                     (nonnull void (^)(NSString *_Nullable, FlutterError *_Nullable))completion {
  FLTImagePickerMethodCallContext *context = [[FLTImagePickerMethodCallContext alloc]
      initWithResult:^void(NSArray<NSString *> *paths, FlutterError *error) {
        if (paths && paths.count != 1) {
          completion(nil, [FlutterError errorWithCode:@"invalid_result"
                                              message:@"Incorrect number of return paths provided"
                                              details:nil]);
        }
        completion(paths.firstObject, error);
      }];
  context.maxImageCount = 1;

  UIImagePickerController *imagePickerController = [self createImagePickerController];
  imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
  imagePickerController.delegate = self;
  imagePickerController.mediaTypes = @[
    (NSString *)kUTTypeMovie, (NSString *)kUTTypeAVIMovie, (NSString *)kUTTypeVideo,
    (NSString *)kUTTypeMPEG4
  ];
  imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;

  if (maxDurationSeconds) {
    NSTimeInterval max = [maxDurationSeconds doubleValue];
    imagePickerController.videoMaximumDuration = max;
  }

  self.callContext = context;

  switch (source.type) {
    case FLTSourceTypeCamera:
      [self checkCameraAuthorizationWithImagePicker:imagePickerController
                                             camera:[self cameraDeviceForSource:source]];
      break;
    case FLTSourceTypeGallery:
      [self checkPhotoAuthorizationWithImagePicker:imagePickerController];
      break;
    default:
      [self sendCallResultWithError:[FlutterError errorWithCode:@"invalid_source"
                                                        message:@"Invalid video source."
                                                        details:nil]];
      break;
  }
}

#pragma mark -

/**
 * If a call is still in progress, cancels it by returning an error and then clearing state.
 *
 * TODO(stuartmorgan): Eliminate this, and instead track context per image picker (e.g., using
 * associated objects).
 */
- (void)cancelInProgressCall {
  if (self.callContext) {
    [self sendCallResultWithError:[FlutterError errorWithCode:@"multiple_request"
                                                      message:@"Cancelled by a second request"
                                                      details:nil]];
    self.callContext = nil;
  }
}

- (void)showCamera:(UIImagePickerControllerCameraDevice)device
    withImagePicker:(UIImagePickerController *)imagePickerController {
  @synchronized(self) {
    if (imagePickerController.beingPresented) {
      return;
    }
  }
  // Camera is not available on simulators
  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] &&
      [UIImagePickerController isCameraDeviceAvailable:device]) {
    imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    imagePickerController.cameraDevice = device;
    [[self viewControllerWithWindow:nil] presentViewController:imagePickerController
                                                      animated:YES
                                                    completion:nil];
  } else {
    UIAlertController *cameraErrorAlert = [UIAlertController
        alertControllerWithTitle:NSLocalizedString(@"Error", @"Alert title when camera unavailable")
                         message:NSLocalizedString(@"Camera not available.",
                                                   "Alert message when camera unavailable")
                  preferredStyle:UIAlertControllerStyleAlert];
    [cameraErrorAlert
        addAction:[UIAlertAction actionWithTitle:NSLocalizedString(
                                                     @"OK", @"Alert button when camera unavailable")
                                           style:UIAlertActionStyleDefault
                                         handler:^(UIAlertAction *action){
                                         }]];
    [[self viewControllerWithWindow:nil] presentViewController:cameraErrorAlert
                                                      animated:YES
                                                    completion:nil];
    [self sendCallResultWithSavedPathList:nil];
  }
}

- (void)checkCameraAuthorizationWithImagePicker:(UIImagePickerController *)imagePickerController
                                         camera:(UIImagePickerControllerCameraDevice)device {
  AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

  switch (status) {
    case AVAuthorizationStatusAuthorized:
      [self showCamera:device withImagePicker:imagePickerController];
      break;
    case AVAuthorizationStatusNotDetermined: {
      [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
                               completionHandler:^(BOOL granted) {
                                 dispatch_async(dispatch_get_main_queue(), ^{
                                   if (granted) {
                                     [self showCamera:device withImagePicker:imagePickerController];
                                   } else {
                                     [self errorNoCameraAccess:AVAuthorizationStatusDenied];
                                   }
                                 });
                               }];
      break;
    }
    case AVAuthorizationStatusDenied:
    case AVAuthorizationStatusRestricted:
    default:
      [self errorNoCameraAccess:status];
      break;
  }
}

- (void)checkPhotoAuthorizationWithImagePicker:(UIImagePickerController *)imagePickerController {
  PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
  switch (status) {
    case PHAuthorizationStatusNotDetermined: {
      [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
          if (status == PHAuthorizationStatusAuthorized) {
            [self showPhotoLibraryWithImagePicker:imagePickerController];
          } else {
            [self errorNoPhotoAccess:status];
          }
        });
      }];
      break;
    }
    case PHAuthorizationStatusAuthorized:
      [self showPhotoLibraryWithImagePicker:imagePickerController];
      break;
    case PHAuthorizationStatusDenied:
    case PHAuthorizationStatusRestricted:
    default:
      [self errorNoPhotoAccess:status];
      break;
  }
}

- (void)checkPhotoAuthorizationForAccessLevel API_AVAILABLE(ios(14)) {
  PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
  switch (status) {
    case PHAuthorizationStatusNotDetermined: {
      [PHPhotoLibrary
          requestAuthorizationForAccessLevel:PHAccessLevelReadWrite
                                     handler:^(PHAuthorizationStatus status) {
                                       dispatch_async(dispatch_get_main_queue(), ^{
                                         if (status == PHAuthorizationStatusAuthorized) {
                                           [self
                                               showPhotoLibraryWithPHPicker:self->
                                                                            _pickerViewController];
                                         } else if (status == PHAuthorizationStatusLimited) {
                                           [self
                                               showPhotoLibraryWithPHPicker:self->
                                                                            _pickerViewController];
                                         } else {
                                           [self errorNoPhotoAccess:status];
                                         }
                                       });
                                     }];
      break;
    }
    case PHAuthorizationStatusAuthorized:
    case PHAuthorizationStatusLimited:
      [self showPhotoLibraryWithPHPicker:_pickerViewController];
      break;
    case PHAuthorizationStatusDenied:
    case PHAuthorizationStatusRestricted:
    default:
      [self errorNoPhotoAccess:status];
      break;
  }
}

- (void)errorNoCameraAccess:(AVAuthorizationStatus)status {
  switch (status) {
    case AVAuthorizationStatusRestricted:
      [self sendCallResultWithError:[FlutterError
                                        errorWithCode:@"camera_access_restricted"
                                              message:@"The user is not allowed to use the camera."
                                              details:nil]];
      break;
    case AVAuthorizationStatusDenied:
    default:
      [self sendCallResultWithError:[FlutterError
                                        errorWithCode:@"camera_access_denied"
                                              message:@"The user did not allow camera access."
                                              details:nil]];
      break;
  }
}

- (void)errorNoPhotoAccess:(PHAuthorizationStatus)status {
  switch (status) {
    case PHAuthorizationStatusRestricted:
      [self sendCallResultWithError:[FlutterError
                                        errorWithCode:@"photo_access_restricted"
                                              message:@"The user is not allowed to use the photo."
                                              details:nil]];
      break;
    case PHAuthorizationStatusDenied:
    default:
      [self sendCallResultWithError:[FlutterError
                                        errorWithCode:@"photo_access_denied"
                                              message:@"The user did not allow photo access."
                                              details:nil]];
      break;
  }
}

- (void)showPhotoLibraryWithPHPicker:(PHPickerViewController *)pickerViewController
    API_AVAILABLE(ios(14)) {
  [[self viewControllerWithWindow:nil] presentViewController:pickerViewController
                                                    animated:YES
                                                  completion:nil];
}

- (void)showPhotoLibraryWithImagePicker:(UIImagePickerController *)imagePickerController {
  imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  [[self viewControllerWithWindow:nil] presentViewController:imagePickerController
                                                    animated:YES
                                                  completion:nil];
}

- (NSNumber *)getDesiredImageQuality:(NSNumber *)imageQuality {
  if (![imageQuality isKindOfClass:[NSNumber class]]) {
    imageQuality = @1;
  } else if (imageQuality.intValue < 0 || imageQuality.intValue > 100) {
    imageQuality = @1;
  } else {
    imageQuality = @([imageQuality floatValue] / 100);
  }
  return imageQuality;
}

#pragma mark - UIAdaptivePresentationControllerDelegate

- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController {
  [self sendCallResultWithSavedPathList:nil];
}

#pragma mark - PHPickerViewControllerDelegate

- (void)picker:(PHPickerViewController *)picker
    didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14)) {
  [picker dismissViewControllerAnimated:YES completion:nil];
  if (results.count == 0) {
    [self sendCallResultWithSavedPathList:nil];
    return;
  }
  dispatch_queue_t backgroundQueue =
      dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
  dispatch_async(backgroundQueue, ^{
    NSNumber *maxWidth = self.callContext.maxSize.width;
    NSNumber *maxHeight = self.callContext.maxSize.height;
    NSNumber *imageQuality = self.callContext.imageQuality;
    NSNumber *desiredImageQuality = [self getDesiredImageQuality:imageQuality];
    NSOperationQueue *operationQueue = [NSOperationQueue new];
    NSMutableArray *pathList = [self createNSMutableArrayWithSize:results.count];

    for (int i = 0; i < results.count; i++) {
      PHPickerResult *result = results[i];
      FLTPHPickerSaveImageToPathOperation *operation =
          [[FLTPHPickerSaveImageToPathOperation alloc] initWithResult:result
                                                            maxHeight:maxHeight
                                                             maxWidth:maxWidth
                                                  desiredImageQuality:desiredImageQuality
                                                       savedPathBlock:^(NSString *savedPath) {
                                                         pathList[i] = savedPath;
                                                       }];
      [operationQueue addOperation:operation];
    }
    [operationQueue waitUntilAllOperationsAreFinished];
    dispatch_async(dispatch_get_main_queue(), ^{
      [self sendCallResultWithSavedPathList:pathList];
    });
  });
}

#pragma mark -

/**
 * Creates an NSMutableArray of a certain size filled with NSNull objects.
 *
 * The difference with initWithCapacity is that initWithCapacity still gives an empty array making
 * it impossible to add objects on an index larger than the size.
 *
 * @param size The length of the required array
 * @return NSMutableArray An array of a specified size
 */
- (NSMutableArray *)createNSMutableArrayWithSize:(NSUInteger)size {
  NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:size];
  for (int i = 0; i < size; [mutableArray addObject:[NSNull null]], i++)
    ;
  return mutableArray;
}

#pragma mark - UIImagePickerControllerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary<NSString *, id> *)info {
  NSURL *videoURL = info[UIImagePickerControllerMediaURL];
  [picker dismissViewControllerAnimated:YES completion:nil];
  // The method dismissViewControllerAnimated does not immediately prevent
  // further didFinishPickingMediaWithInfo invocations. A nil check is necessary
  // to prevent below code to be unwantly executed multiple times and cause a
  // crash.
  if (!self.callContext) {
    return;
  }
  if (videoURL != nil) {
    if (@available(iOS 13.0, *)) {
      NSString *fileName = [videoURL lastPathComponent];
      NSURL *destination =
          [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];

      if ([[NSFileManager defaultManager] isReadableFileAtPath:[videoURL path]]) {
        NSError *error;
        if (![[videoURL path] isEqualToString:[destination path]]) {
          [[NSFileManager defaultManager] copyItemAtURL:videoURL toURL:destination error:&error];

          if (error) {
            [self sendCallResultWithError:[FlutterError
                                              errorWithCode:@"flutter_image_picker_copy_video_error"
                                                    message:@"Could not cache the video file."
                                                    details:nil]];
            return;
          }
        }
        videoURL = destination;
      }
    }
    [self sendCallResultWithSavedPathList:@[ videoURL.path ]];
  } else {
    UIImage *image = info[UIImagePickerControllerEditedImage];
    if (image == nil) {
      image = info[UIImagePickerControllerOriginalImage];
    }
    NSNumber *maxWidth = self.callContext.maxSize.width;
    NSNumber *maxHeight = self.callContext.maxSize.height;
    NSNumber *imageQuality = self.callContext.imageQuality;
    NSNumber *desiredImageQuality = [self getDesiredImageQuality:imageQuality];

    PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromImagePickerInfo:info];

    if (maxWidth != nil || maxHeight != nil) {
      image = [FLTImagePickerImageUtil scaledImage:image
                                          maxWidth:maxWidth
                                         maxHeight:maxHeight
                               isMetadataAvailable:YES];
    }

    if (!originalAsset) {
      // Image picked without an original asset (e.g. User took a photo directly)
      [self saveImageWithPickerInfo:info image:image imageQuality:desiredImageQuality];
    } else {
      void (^resultHandler)(NSData *imageData, NSString *dataUTI, NSDictionary *info) = ^(
          NSData *_Nullable imageData, NSString *_Nullable dataUTI, NSDictionary *_Nullable info) {
        // maxWidth and maxHeight are used only for GIF images.
        [self saveImageWithOriginalImageData:imageData
                                       image:image
                                    maxWidth:maxWidth
                                   maxHeight:maxHeight
                                imageQuality:desiredImageQuality];
      };
      if (@available(iOS 13.0, *)) {
        [[PHImageManager defaultManager]
            requestImageDataAndOrientationForAsset:originalAsset
                                           options:nil
                                     resultHandler:^(NSData *_Nullable imageData,
                                                     NSString *_Nullable dataUTI,
                                                     CGImagePropertyOrientation orientation,
                                                     NSDictionary *_Nullable info) {
                                       resultHandler(imageData, dataUTI, info);
                                     }];
      } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [[PHImageManager defaultManager]
            requestImageDataForAsset:originalAsset
                             options:nil
                       resultHandler:^(NSData *_Nullable imageData, NSString *_Nullable dataUTI,
                                       UIImageOrientation orientation,
                                       NSDictionary *_Nullable info) {
                         resultHandler(imageData, dataUTI, info);
                       }];
#pragma clang diagnostic pop
      }
    }
  }
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
  [picker dismissViewControllerAnimated:YES completion:nil];
  [self sendCallResultWithSavedPathList:nil];
}

#pragma mark -

- (void)saveImageWithOriginalImageData:(NSData *)originalImageData
                                 image:(UIImage *)image
                              maxWidth:(NSNumber *)maxWidth
                             maxHeight:(NSNumber *)maxHeight
                          imageQuality:(NSNumber *)imageQuality {
  NSString *savedPath =
      [FLTImagePickerPhotoAssetUtil saveImageWithOriginalImageData:originalImageData
                                                             image:image
                                                          maxWidth:maxWidth
                                                         maxHeight:maxHeight
                                                      imageQuality:imageQuality];
  [self sendCallResultWithSavedPathList:@[ savedPath ]];
}

- (void)saveImageWithPickerInfo:(NSDictionary *)info
                          image:(UIImage *)image
                   imageQuality:(NSNumber *)imageQuality {
  NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:info
                                                                        image:image
                                                                 imageQuality:imageQuality];
  [self sendCallResultWithSavedPathList:@[ savedPath ]];
}

- (void)sendCallResultWithSavedPathList:(nullable NSArray *)pathList {
  if (!self.callContext) {
    return;
  }

  if ([pathList containsObject:[NSNull null]]) {
    self.callContext.result(nil, [FlutterError errorWithCode:@"create_error"
                                                     message:@"pathList's items should not be null"
                                                     details:nil]);
  } else {
    self.callContext.result(pathList, nil);
  }
  self.callContext = nil;
}

/**
 * Sends the given error via `callContext.result` as the result of the original platform channel
 * method call, clearing the in-progress call state.
 *
 * @param error The error to return.
 */
- (void)sendCallResultWithError:(FlutterError *)error {
  if (!self.callContext) {
    return;
  }
  self.callContext.result(nil, error);
  self.callContext = nil;
}

@end
