// 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 "FlutterWebView.h"
#import "FLTWKNavigationDelegate.h"
#import "FLTWKProgressionDelegate.h"
#import "FlutterWebView_Test.h"
#import "JavaScriptChannelHandler.h"

@implementation FLTWebViewFactory {
  NSObject<FlutterBinaryMessenger> *_messenger;
  FLTCookieManager *_cookieManager;
}

- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
                    cookieManager:(FLTCookieManager *)cookieManager {
  self = [super init];
  if (self) {
    _messenger = messenger;
    _cookieManager = cookieManager;
  }
  return self;
}

- (NSObject<FlutterMessageCodec> *)createArgsCodec {
  return [FlutterStandardMessageCodec sharedInstance];
}

- (NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame
                                    viewIdentifier:(int64_t)viewId
                                         arguments:(id _Nullable)args {
  if (@available(iOS 11.0, *)) {
    [_cookieManager setCookiesForData:args[@"cookies"]];
  }

  FLTWebViewController *webviewController = [[FLTWebViewController alloc] initWithFrame:frame
                                                                         viewIdentifier:viewId
                                                                              arguments:args
                                                                        binaryMessenger:_messenger];
  return webviewController;
}

@end

@implementation FLTWKWebView

- (void)setFrame:(CGRect)frame {
  [super setFrame:frame];
  self.scrollView.contentInset = UIEdgeInsetsZero;
  // We don't want the contentInsets to be adjusted by iOS, flutter should always take control of
  // webview's contentInsets.
  // self.scrollView.contentInset = UIEdgeInsetsZero;
  if (@available(iOS 11, *)) {
    // Above iOS 11, adjust contentInset to compensate the adjustedContentInset so the sum will
    // always be 0.
    if (UIEdgeInsetsEqualToEdgeInsets(self.scrollView.adjustedContentInset, UIEdgeInsetsZero)) {
      return;
    }
    UIEdgeInsets insetToAdjust = self.scrollView.adjustedContentInset;
    self.scrollView.contentInset = UIEdgeInsetsMake(-insetToAdjust.top, -insetToAdjust.left,
                                                    -insetToAdjust.bottom, -insetToAdjust.right);
  }
}

@end

@implementation FLTWebViewController {
  FLTWKWebView *_webView;
  int64_t _viewId;
  FlutterMethodChannel *_channel;
  NSString *_currentUrl;
  // The set of registered JavaScript channel names.
  NSMutableSet *_javaScriptChannelNames;
  FLTWKNavigationDelegate *_navigationDelegate;
  FLTWKProgressionDelegate *_progressionDelegate;
}

- (instancetype)initWithFrame:(CGRect)frame
               viewIdentifier:(int64_t)viewId
                    arguments:(id _Nullable)args
              binaryMessenger:(NSObject<FlutterBinaryMessenger> *)messenger {
  if (self = [super init]) {
    _viewId = viewId;

    NSString *channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId];
    _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
    _javaScriptChannelNames = [[NSMutableSet alloc] init];

    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    if ([args[@"javascriptChannelNames"] isKindOfClass:[NSArray class]]) {
      NSArray *javaScriptChannelNames = args[@"javascriptChannelNames"];
      [_javaScriptChannelNames addObjectsFromArray:javaScriptChannelNames];
      [self registerJavaScriptChannels:_javaScriptChannelNames controller:userContentController];
    }

    NSDictionary<NSString *, id> *settings = args[@"settings"];

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    [self applyConfigurationSettings:settings toConfiguration:configuration];
    configuration.userContentController = userContentController;
    [self updateAutoMediaPlaybackPolicy:args[@"autoMediaPlaybackPolicy"]
                        inConfiguration:configuration];

    _webView = [[FLTWKWebView alloc] initWithFrame:frame configuration:configuration];

    // Background color
    NSNumber *backgroundColorNSNumber = args[@"backgroundColor"];
    if ([backgroundColorNSNumber isKindOfClass:[NSNumber class]]) {
      int backgroundColorInt = [backgroundColorNSNumber intValue];
      UIColor *backgroundColor = [UIColor colorWithRed:(backgroundColorInt >> 16 & 0xff) / 255.0
                                                 green:(backgroundColorInt >> 8 & 0xff) / 255.0
                                                  blue:(backgroundColorInt & 0xff) / 255.0
                                                 alpha:(backgroundColorInt >> 24 & 0xff) / 255.0];
      _webView.opaque = NO;
      _webView.backgroundColor = UIColor.clearColor;
      _webView.scrollView.backgroundColor = backgroundColor;
    }

    _navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel];
    _webView.UIDelegate = self;
    _webView.navigationDelegate = _navigationDelegate;
    __weak __typeof__(self) weakSelf = self;
    [_channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
      [weakSelf onMethodCall:call result:result];
    }];

    if (@available(iOS 11.0, *)) {
      _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
      if (@available(iOS 13.0, *)) {
        _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO;
      }
    }

    [self applySettings:settings];
    // TODO(amirh): return an error if apply settings failed once it's possible to do so.
    // https://github.com/flutter/flutter/issues/36228

    NSString *initialUrl = args[@"initialUrl"];
    if ([initialUrl isKindOfClass:[NSString class]]) {
      NSURL *url = [NSURL URLWithString:initialUrl];
      if (url) {
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        [_webView loadRequest:request];
      }
    }
  }
  return self;
}

- (void)dealloc {
  if (_progressionDelegate != nil) {
    [_progressionDelegate stopObservingProgress:_webView];
  }
}

- (UIView *)view {
  return _webView;
}

- (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
  if ([[call method] isEqualToString:@"updateSettings"]) {
    [self onUpdateSettings:call result:result];
  } else if ([[call method] isEqualToString:@"loadFile"]) {
    [self onLoadFile:call result:result];
  } else if ([[call method] isEqualToString:@"loadFlutterAsset"]) {
    [self onLoadFlutterAsset:call result:result];
  } else if ([[call method] isEqualToString:@"loadHtmlString"]) {
    [self onLoadHtmlString:call result:result];
  } else if ([[call method] isEqualToString:@"loadUrl"]) {
    [self onLoadUrl:call result:result];
  } else if ([[call method] isEqualToString:@"loadRequest"]) {
    [self onLoadRequest:call result:result];
  } else if ([[call method] isEqualToString:@"canGoBack"]) {
    [self onCanGoBack:call result:result];
  } else if ([[call method] isEqualToString:@"canGoForward"]) {
    [self onCanGoForward:call result:result];
  } else if ([[call method] isEqualToString:@"goBack"]) {
    [self onGoBack:call result:result];
  } else if ([[call method] isEqualToString:@"goForward"]) {
    [self onGoForward:call result:result];
  } else if ([[call method] isEqualToString:@"reload"]) {
    [self onReload:call result:result];
  } else if ([[call method] isEqualToString:@"currentUrl"]) {
    [self onCurrentUrl:call result:result];
  } else if ([[call method] isEqualToString:@"evaluateJavascript"]) {
    [self onEvaluateJavaScript:call result:result];
  } else if ([[call method] isEqualToString:@"runJavascript"]) {
    [self onRunJavaScript:call result:result sendReturnValue:NO];
  } else if ([[call method] isEqualToString:@"runJavascriptReturningResult"]) {
    [self onRunJavaScript:call result:result sendReturnValue:YES];
  } else if ([[call method] isEqualToString:@"addJavascriptChannels"]) {
    [self onAddJavaScriptChannels:call result:result];
  } else if ([[call method] isEqualToString:@"removeJavascriptChannels"]) {
    [self onRemoveJavaScriptChannels:call result:result];
  } else if ([[call method] isEqualToString:@"clearCache"]) {
    [self clearCache:result];
  } else if ([[call method] isEqualToString:@"getTitle"]) {
    [self onGetTitle:result];
  } else if ([[call method] isEqualToString:@"scrollTo"]) {
    [self onScrollTo:call result:result];
  } else if ([[call method] isEqualToString:@"scrollBy"]) {
    [self onScrollBy:call result:result];
  } else if ([[call method] isEqualToString:@"getScrollX"]) {
    [self getScrollX:call result:result];
  } else if ([[call method] isEqualToString:@"getScrollY"]) {
    [self getScrollY:call result:result];
  } else {
    result(FlutterMethodNotImplemented);
  }
}

- (void)onUpdateSettings:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSString *error = [self applySettings:[call arguments]];
  if (error == nil) {
    result(nil);
    return;
  }
  result([FlutterError errorWithCode:@"updateSettings_failed" message:error details:nil]);
}

- (void)onLoadFile:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSString *error = nil;
  if (![FLTWebViewController isValidStringArgument:[call arguments] withErrorMessage:&error]) {
    result([FlutterError errorWithCode:@"loadFile_failed"
                               message:@"Failed parsing file path."
                               details:error]);
    return;
  }

  NSURL *url = [NSURL fileURLWithPath:[call arguments] isDirectory:NO];

  if (!url) {
    NSString *errorDetails = [NSString stringWithFormat:@"Initializing NSURL with the supplied "
                                                        @"'%@' path resulted in a nil value.",
                                                        [call arguments]];
    result([FlutterError errorWithCode:@"loadFile_failed"
                               message:@"Failed parsing file path."
                               details:errorDetails]);
    return;
  }

  NSURL *baseUrl = [url URLByDeletingLastPathComponent];

  [_webView loadFileURL:url allowingReadAccessToURL:baseUrl];
  result(nil);
}

- (void)onLoadFlutterAsset:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSString *error = nil;
  if (![FLTWebViewController isValidStringArgument:[call arguments] withErrorMessage:&error]) {
    result([FlutterError errorWithCode:@"loadFlutterAsset_invalidKey"
                               message:@"Supplied asset key is not valid."
                               details:error]);
    return;
  }

  NSString *assetKey = [call arguments];
  NSString *assetFilePath = [FlutterDartProject lookupKeyForAsset:assetKey];
  NSURL *url = [[NSBundle mainBundle] URLForResource:[assetFilePath stringByDeletingPathExtension]
                                       withExtension:assetFilePath.pathExtension];

  if (!url) {
    result([FlutterError
        errorWithCode:@"loadFlutterAsset_invalidKey"
              message:@"Failed parsing file path for supplied key."
              details:[NSString
                          stringWithFormat:@"Failed to convert path '%@' into NSURL for key '%@'.",
                                           assetFilePath, assetKey]]);
    return;
  }

  [_webView loadFileURL:url allowingReadAccessToURL:[url URLByDeletingLastPathComponent]];
  result(nil);
}

- (void)onLoadHtmlString:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSDictionary *arguments = [call arguments];
  if (![arguments isKindOfClass:NSDictionary.class]) {
    result([FlutterError
        errorWithCode:@"loadHtmlString_failed"
              message:@"Failed parsing arguments."
              details:@"Arguments should be a dictionary containing at least a 'html' element and "
                      @"optionally a 'baseUrl' argument. For example: `@{ @\"html\": @\"some html "
                      @"code\", @\"baseUrl\": @\"https://flutter.dev\" }`"]);
    return;
  }

  NSString *htmlString = [call arguments][@"html"];
  NSString *baseUrl =
      [call arguments][@"baseUrl"] == [NSNull null] ? nil : [call arguments][@"baseUrl"];
  NSString *error = nil;
  if (![FLTWebViewController isValidStringArgument:htmlString withErrorMessage:&error]) {
    result([FlutterError errorWithCode:@"loadHtmlString_failed"
                               message:@"Failed parsing HTML string argument."
                               details:error]);
    return;
  }

  [_webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:baseUrl]];
  result(nil);
}

- (void)onLoadUrl:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSMutableDictionary *requestData = [[NSMutableDictionary alloc] init];
  if (call.arguments[@"url"]) {
    requestData[@"uri"] = call.arguments[@"url"];
  }
  if (call.arguments[@"headers"]) {
    requestData[@"headers"] = call.arguments[@"headers"];
  }
  NSURLRequest *request = [self buildNSURLRequest:@{@"request" : requestData}];
  if (!request) {
    result([FlutterError
        errorWithCode:@"loadUrl_failed"
              message:@"Failed parsing the URL"
              details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]);
  } else {
    [_webView loadRequest:request];
    result(nil);
  }
}

- (void)onLoadRequest:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSURLRequest *request = [self buildNSURLRequest:[call arguments]];
  if (!request) {
    result([FlutterError
        errorWithCode:@"loadRequest_failed"
              message:@"Failed parsing the URL"
              details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]);
  } else {
    [_webView loadRequest:request];
    result(nil);
  }
}

- (void)onCanGoBack:(FlutterMethodCall *)call result:(FlutterResult)result {
  BOOL canGoBack = [_webView canGoBack];
  result(@(canGoBack));
}

- (void)onCanGoForward:(FlutterMethodCall *)call result:(FlutterResult)result {
  BOOL canGoForward = [_webView canGoForward];
  result(@(canGoForward));
}

- (void)onGoBack:(FlutterMethodCall *)call result:(FlutterResult)result {
  [_webView goBack];
  result(nil);
}

- (void)onGoForward:(FlutterMethodCall *)call result:(FlutterResult)result {
  [_webView goForward];
  result(nil);
}

- (void)onReload:(FlutterMethodCall *)call result:(FlutterResult)result {
  [_webView reload];
  result(nil);
}

- (void)onCurrentUrl:(FlutterMethodCall *)call result:(FlutterResult)result {
  _currentUrl = [[_webView URL] absoluteString];
  result(_currentUrl);
}

- (void)onEvaluateJavaScript:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSString *jsString = [call arguments];
  if (!jsString) {
    result([FlutterError errorWithCode:@"evaluateJavaScript_failed"
                               message:@"JavaScript String cannot be null"
                               details:nil]);
    return;
  }
  [_webView evaluateJavaScript:jsString
             completionHandler:^(_Nullable id evaluateResult, NSError *_Nullable error) {
               if (error) {
                 result([FlutterError
                     errorWithCode:@"evaluateJavaScript_failed"
                           message:@"Failed evaluating JavaScript"
                           details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@",
                                                              jsString, error]]);
               } else {
                 result([NSString stringWithFormat:@"%@", evaluateResult]);
               }
             }];
}

- (void)onRunJavaScript:(FlutterMethodCall *)call
                 result:(FlutterResult)result
        sendReturnValue:(BOOL)sendReturnValue {
  NSString *jsString = [call arguments];
  if (!jsString) {
    result([FlutterError errorWithCode:@"runJavascript_failed"
                               message:@"JavaScript String cannot be null"
                               details:nil]);
    return;
  }
  [_webView
      evaluateJavaScript:jsString
       completionHandler:^(_Nullable id evaluateResult, NSError *_Nullable error) {
         if (error) {
           // WebKit will throw an error (WKErrorJavaScriptResultTypeIsUnsupported) when the
           // type of the evaluated value is unsupported. This also goes for
           // `null` and `undefined` on iOS 14+, for example when running a void function.
           // For ease of use this specific error is ignored when no return value is expected.
           BOOL sendError =
               sendReturnValue || error.code != WKErrorJavaScriptResultTypeIsUnsupported;
           result(sendError
                      ? [FlutterError
                            errorWithCode:(sendReturnValue ? @"runJavascriptReturningResult_failed"
                                                           : @"runJavascript_failed")
                                  message:@"Failed running JavaScript"
                                  details:[NSString
                                              stringWithFormat:@"JavaScript string was: '%@'\n%@",
                                                               jsString, error]]
                      : nil);
           return;
         }
         result(sendReturnValue ? [NSString stringWithFormat:@"%@", evaluateResult] : nil);
       }];
}

- (void)onAddJavaScriptChannels:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSArray *channelNames = [call arguments];
  NSSet *channelNamesSet = [[NSSet alloc] initWithArray:channelNames];
  [_javaScriptChannelNames addObjectsFromArray:channelNames];
  [self registerJavaScriptChannels:channelNamesSet
                        controller:_webView.configuration.userContentController];
  result(nil);
}

- (void)onRemoveJavaScriptChannels:(FlutterMethodCall *)call result:(FlutterResult)result {
  // WkWebView does not support removing a single user script, so instead we remove all
  // user scripts, all message handlers. And re-register channels that shouldn't be removed.
  [_webView.configuration.userContentController removeAllUserScripts];
  for (NSString *channelName in _javaScriptChannelNames) {
    [_webView.configuration.userContentController removeScriptMessageHandlerForName:channelName];
  }

  NSArray *channelNamesToRemove = [call arguments];
  for (NSString *channelName in channelNamesToRemove) {
    [_javaScriptChannelNames removeObject:channelName];
  }

  [self registerJavaScriptChannels:_javaScriptChannelNames
                        controller:_webView.configuration.userContentController];
  result(nil);
}

- (void)clearCache:(FlutterResult)result {
  NSSet *cacheDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
  WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
  NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
  [dataStore removeDataOfTypes:cacheDataTypes
                 modifiedSince:dateFrom
             completionHandler:^{
               result(nil);
             }];
}

- (void)onGetTitle:(FlutterResult)result {
  NSString *title = _webView.title;
  result(title);
}

- (void)onScrollTo:(FlutterMethodCall *)call result:(FlutterResult)result {
  NSDictionary *arguments = [call arguments];
  int x = [arguments[@"x"] intValue];
  int y = [arguments[@"y"] intValue];

  _webView.scrollView.contentOffset = CGPointMake(x, y);
  result(nil);
}

- (void)onScrollBy:(FlutterMethodCall *)call result:(FlutterResult)result {
  CGPoint contentOffset = _webView.scrollView.contentOffset;

  NSDictionary *arguments = [call arguments];
  int x = [arguments[@"x"] intValue] + contentOffset.x;
  int y = [arguments[@"y"] intValue] + contentOffset.y;

  _webView.scrollView.contentOffset = CGPointMake(x, y);
  result(nil);
}

- (void)getScrollX:(FlutterMethodCall *)call result:(FlutterResult)result {
  int offsetX = _webView.scrollView.contentOffset.x;
  result(@(offsetX));
}

- (void)getScrollY:(FlutterMethodCall *)call result:(FlutterResult)result {
  int offsetY = _webView.scrollView.contentOffset.y;
  result(@(offsetY));
}

// Returns nil when successful, or an error message when one or more keys are unknown.
- (NSString *)applySettings:(NSDictionary<NSString *, id> *)settings {
  NSMutableArray<NSString *> *unknownKeys = [[NSMutableArray alloc] init];
  for (NSString *key in settings) {
    if ([key isEqualToString:@"jsMode"]) {
      NSNumber *mode = settings[key];
      [self updateJsMode:mode];
    } else if ([key isEqualToString:@"hasNavigationDelegate"]) {
      NSNumber *hasDartNavigationDelegate = settings[key];
      _navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue];
    } else if ([key isEqualToString:@"hasProgressTracking"]) {
      NSNumber *hasProgressTrackingValue = settings[key];
      bool hasProgressTracking = [hasProgressTrackingValue boolValue];
      if (hasProgressTracking) {
        _progressionDelegate = [[FLTWKProgressionDelegate alloc] initWithWebView:_webView
                                                                         channel:_channel];
      }
    } else if ([key isEqualToString:@"debuggingEnabled"]) {
      // no-op debugging is always enabled on iOS.
    } else if ([key isEqualToString:@"gestureNavigationEnabled"]) {
      NSNumber *allowsBackForwardNavigationGestures = settings[key];
      _webView.allowsBackForwardNavigationGestures =
          [allowsBackForwardNavigationGestures boolValue];
    } else if ([key isEqualToString:@"userAgent"]) {
      NSString *userAgent = settings[key];
      [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent];
    } else if ([key isEqualToString:@"zoomEnabled"]) {
      NSNumber *zoomEnabled = settings[key];
      _navigationDelegate.shouldEnableZoom = [zoomEnabled boolValue];
    } else {
      [unknownKeys addObject:key];
    }
  }
  if ([unknownKeys count] == 0) {
    return nil;
  }
  return [NSString stringWithFormat:@"webview_flutter: unknown setting keys: {%@}",
                                    [unknownKeys componentsJoinedByString:@", "]];
}

- (void)applyConfigurationSettings:(NSDictionary<NSString *, id> *)settings
                   toConfiguration:(WKWebViewConfiguration *)configuration {
  NSAssert(configuration != _webView.configuration,
           @"configuration needs to be updated before webView.configuration.");
  for (NSString *key in settings) {
    if ([key isEqualToString:@"allowsInlineMediaPlayback"]) {
      NSNumber *allowsInlineMediaPlayback = settings[key];
      configuration.allowsInlineMediaPlayback = [allowsInlineMediaPlayback boolValue];
    }
  }
}

- (void)updateJsMode:(NSNumber *)mode {
  WKPreferences *preferences = [[_webView configuration] preferences];
  switch ([mode integerValue]) {
    case 0:  // disabled
      [preferences setJavaScriptEnabled:NO];
      break;
    case 1:  // unrestricted
      [preferences setJavaScriptEnabled:YES];
      break;
    default:
      NSLog(@"webview_flutter: unknown JavaScript mode: %@", mode);
  }
}

- (void)updateAutoMediaPlaybackPolicy:(NSNumber *)policy
                      inConfiguration:(WKWebViewConfiguration *)configuration {
  switch ([policy integerValue]) {
    case 0:  // require_user_action_for_all_media_types
      if (@available(iOS 10.0, *)) {
        configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
      } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        configuration.requiresUserActionForMediaPlayback = true;
#pragma clang diagnostic pop
      }
      break;
    case 1:  // always_allow
      if (@available(iOS 10.0, *)) {
        configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
      } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        configuration.requiresUserActionForMediaPlayback = false;
#pragma clang diagnostic pop
      }
      break;
    default:
      NSLog(@"webview_flutter: unknown auto media playback policy: %@", policy);
  }
}

/**
 * Parses the method call arguments and converts them to an NSURLRequest object.
 *
 * @param arguments the method call arguments.
 *
 * @return NSURLRequest object.
 */
- (NSURLRequest *)buildNSURLRequest:(NSDictionary<NSString *, id> *)arguments {
  id requestParameters = arguments[@"request"];
  if (![requestParameters isKindOfClass:[NSDictionary class]]) {
    return nil;
  }

  NSString *urlString = requestParameters[@"uri"];
  if (!urlString) {
    return nil;
  }

  NSURL *url = [NSURL URLWithString:urlString];
  if (!url) {
    return nil;
  }

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

  NSString *httpMethod = requestParameters[@"method"];
  if (httpMethod) {
    [request setHTTPMethod:httpMethod];
  }

  id httpBody = requestParameters[@"body"];
  if ([httpBody isKindOfClass:[FlutterStandardTypedData class]]) {
    [request setHTTPBody:[httpBody data]];
  }

  id headers = requestParameters[@"headers"];
  if ([headers isKindOfClass:[NSDictionary class]]) {
    [request setAllHTTPHeaderFields:headers];
  }

  return request;
}

- (void)registerJavaScriptChannels:(NSSet *)channelNames
                        controller:(WKUserContentController *)userContentController {
  for (NSString *channelName in channelNames) {
    FLTJavaScriptChannel *channel =
        [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel
                                      javaScriptChannelName:channelName];
    [userContentController addScriptMessageHandler:channel name:channelName];
    NSString *wrapperSource = [NSString
        stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName];
    WKUserScript *wrapperScript =
        [[WKUserScript alloc] initWithSource:wrapperSource
                               injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                            forMainFrameOnly:NO];
    [userContentController addUserScript:wrapperScript];
  }
}

- (void)updateUserAgent:(NSString *)userAgent {
  [_webView setCustomUserAgent:userAgent];
}

/**
 * Validates if the given `argument` is a non-null, non-empty string.
 *
 * @param argument The argument that should be validated.
 * @param errorDetails An optional NSString variable which will contain a detailed error message in
 * case the supplied argument is not valid.
 * @return `YES` if the given `argument` is a valid non-null, non-empty string; otherwise `NO`.
 */
+ (BOOL)isValidStringArgument:(id)argument withErrorMessage:(NSString **)errorDetails {
  if (!argument) {
    if (errorDetails) {
      *errorDetails = @"Argument is nil.";
    }
    return NO;
  }
  if (![argument isKindOfClass:NSString.class]) {
    if (errorDetails) {
      *errorDetails = @"Argument is not of type NSString.";
    }
    return NO;
  }
  if (![argument length]) {
    if (errorDetails) {
      *errorDetails = @"Argument contains an empty string.";
    }
    return NO;
  }

  return YES;
}

#pragma mark WKUIDelegate

- (WKWebView *)webView:(WKWebView *)webView
    createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
               forNavigationAction:(WKNavigationAction *)navigationAction
                    windowFeatures:(WKWindowFeatures *)windowFeatures {
  if (!navigationAction.targetFrame.isMainFrame) {
    [webView loadRequest:navigationAction.request];
  }

  return nil;
}

@end
