// 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 alloc] init];
  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;

  if (context.requestFullMetadata) {
    [self checkPhotoAuthorizationForAccessLevel];
  } else {
    [self showPhotoLibraryWithPHPicker:_pickerViewController];
  }
}

- (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:
      if (@available(iOS 11, *)) {
        if (context.requestFullMetadata) {
          [self checkPhotoAuthorizationWithImagePicker:imagePickerController];
        } else {
          [self showPhotoLibraryWithImagePicker:imagePickerController];
        }
      } else {
        // Prior to iOS 11, accessing gallery requires authorization
        [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
               fullMetadata:(NSNumber *)fullMetadata
                 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;
  context.requestFullMetadata = [fullMetadata boolValue];

  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
                     fullMetadata:(NSNumber *)fullMetadata
                       completion:(nonnull void (^)(NSArray<NSString *> *_Nullable,
                                                    FlutterError *_Nullable))completion {
  FLTImagePickerMethodCallContext *context =
      [[FLTImagePickerMethodCallContext alloc] initWithResult:completion];
  context.maxSize = maxSize;
  context.imageQuality = imageQuality;
  context.requestFullMetadata = [fullMetadata boolValue];

  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
                 fullMetadata:self.callContext.requestFullMetadata
               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;
    if (_callContext.requestFullMetadata) {
      // Full metadata are available only in PHAsset, which requires gallery permission.
      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
