// 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 "flutter/shell/platform/darwin/ios/framework/Headers/FlutterAppDelegate.h"

#import "flutter/fml/logging.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate_Test.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate_internal.h"

static NSString* const kUIBackgroundMode = @"UIBackgroundModes";
static NSString* const kRemoteNotificationCapabitiliy = @"remote-notification";
static NSString* const kBackgroundFetchCapatibility = @"fetch";
static NSString* const kRestorationStateAppModificationKey = @"mod-date";

@interface FlutterAppDelegate ()
@property(nonatomic, copy) FlutterViewController* (^rootFlutterViewControllerGetter)(void);
@end

@implementation FlutterAppDelegate {
  FlutterPluginAppLifeCycleDelegate* _lifeCycleDelegate;
}

- (instancetype)init {
  if (self = [super init]) {
    _lifeCycleDelegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
  }
  return self;
}

- (void)dealloc {
  [_lifeCycleDelegate release];
  [_rootFlutterViewControllerGetter release];
  [_window release];
  [super dealloc];
}

- (BOOL)application:(UIApplication*)application
    willFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
  return [_lifeCycleDelegate application:application willFinishLaunchingWithOptions:launchOptions];
}

- (BOOL)application:(UIApplication*)application
    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
  return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions];
}

// Returns the key window's rootViewController, if it's a FlutterViewController.
// Otherwise, returns nil.
- (FlutterViewController*)rootFlutterViewController {
  if (_rootFlutterViewControllerGetter != nil) {
    return _rootFlutterViewControllerGetter();
  }
  UIViewController* rootViewController = _window.rootViewController;
  if ([rootViewController isKindOfClass:[FlutterViewController class]]) {
    return (FlutterViewController*)rootViewController;
  }
  return nil;
}

// Do not remove, some clients may be calling these via `super`.
- (void)applicationDidEnterBackground:(UIApplication*)application {
}

// Do not remove, some clients may be calling these via `super`.
- (void)applicationWillEnterForeground:(UIApplication*)application {
}

// Do not remove, some clients may be calling these via `super`.
- (void)applicationWillResignActive:(UIApplication*)application {
}

// Do not remove, some clients may be calling these via `super`.
- (void)applicationDidBecomeActive:(UIApplication*)application {
}

// Do not remove, some clients may be calling these via `super`.
- (void)applicationWillTerminate:(UIApplication*)application {
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void)application:(UIApplication*)application
    didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
  [_lifeCycleDelegate application:application
      didRegisterUserNotificationSettings:notificationSettings];
}
#pragma GCC diagnostic pop

- (void)application:(UIApplication*)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
  [_lifeCycleDelegate application:application
      didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication*)application
    didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
  [_lifeCycleDelegate application:application
      didFailToRegisterForRemoteNotificationsWithError:error];
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- (void)application:(UIApplication*)application
    didReceiveLocalNotification:(UILocalNotification*)notification {
  [_lifeCycleDelegate application:application didReceiveLocalNotification:notification];
}
#pragma GCC diagnostic pop

- (void)userNotificationCenter:(UNUserNotificationCenter*)center
       willPresentNotification:(UNNotification*)notification
         withCompletionHandler:
             (void (^)(UNNotificationPresentationOptions options))completionHandler
    NS_AVAILABLE_IOS(10_0) {
  if (@available(iOS 10.0, *)) {
    if ([_lifeCycleDelegate respondsToSelector:_cmd]) {
      [_lifeCycleDelegate userNotificationCenter:center
                         willPresentNotification:notification
                           withCompletionHandler:completionHandler];
    }
  }
}

/**
 * Calls all plugins registered for `UNUserNotificationCenterDelegate` callbacks.
 */
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
    didReceiveNotificationResponse:(UNNotificationResponse*)response
             withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10_0) {
  if (@available(iOS 10.0, *)) {
    if ([_lifeCycleDelegate respondsToSelector:_cmd]) {
      [_lifeCycleDelegate userNotificationCenter:center
                  didReceiveNotificationResponse:response
                           withCompletionHandler:completionHandler];
    }
  }
}

- (BOOL)openURL:(NSURL*)url {
  NSNumber* isDeepLinkingEnabled =
      [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FlutterDeepLinkingEnabled"];
  if (!isDeepLinkingEnabled.boolValue) {
    // Not set or NO.
    return NO;
  } else {
    FlutterViewController* flutterViewController = [self rootFlutterViewController];
    if (flutterViewController) {
      [flutterViewController.engine
          waitForFirstFrame:3.0
                   callback:^(BOOL didTimeout) {
                     if (didTimeout) {
                       FML_LOG(ERROR)
                           << "Timeout waiting for the first frame when launching an URL.";
                     } else {
                       NSString* fullRoute = url.path;
                       if ([url.query length] != 0) {
                         fullRoute = [NSString stringWithFormat:@"%@?%@", fullRoute, url.query];
                       }
                       if ([url.fragment length] != 0) {
                         fullRoute = [NSString stringWithFormat:@"%@#%@", fullRoute, url.fragment];
                       }
                       [flutterViewController.engine.navigationChannel invokeMethod:@"pushRoute"
                                                                          arguments:fullRoute];
                     }
                   }];
      return YES;
    } else {
      FML_LOG(ERROR) << "Attempting to open an URL without a Flutter RootViewController.";
      return NO;
    }
  }
}

- (BOOL)application:(UIApplication*)application
            openURL:(NSURL*)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
  if ([_lifeCycleDelegate application:application openURL:url options:options]) {
    return YES;
  }
  return [self openURL:url];
}

- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
  return [_lifeCycleDelegate application:application handleOpenURL:url];
}

- (BOOL)application:(UIApplication*)application
              openURL:(NSURL*)url
    sourceApplication:(NSString*)sourceApplication
           annotation:(id)annotation {
  return [_lifeCycleDelegate application:application
                                 openURL:url
                       sourceApplication:sourceApplication
                              annotation:annotation];
}

- (void)application:(UIApplication*)application
    performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
               completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) {
  [_lifeCycleDelegate application:application
      performActionForShortcutItem:shortcutItem
                 completionHandler:completionHandler];
}

- (void)application:(UIApplication*)application
    handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
                      completionHandler:(nonnull void (^)())completionHandler {
  [_lifeCycleDelegate application:application
      handleEventsForBackgroundURLSession:identifier
                        completionHandler:completionHandler];
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000
- (BOOL)application:(UIApplication*)application
    continueUserActivity:(NSUserActivity*)userActivity
      restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>>* __nullable
                                       restorableObjects))restorationHandler {
#else
- (BOOL)application:(UIApplication*)application
    continueUserActivity:(NSUserActivity*)userActivity
      restorationHandler:(void (^)(NSArray* __nullable restorableObjects))restorationHandler {
#endif
  if ([_lifeCycleDelegate application:application
                 continueUserActivity:userActivity
                   restorationHandler:restorationHandler]) {
    return YES;
  }
  return [self openURL:userActivity.webpageURL];
}

#pragma mark - FlutterPluginRegistry methods. All delegating to the rootViewController

- (NSObject<FlutterPluginRegistrar>*)registrarForPlugin:(NSString*)pluginKey {
  FlutterViewController* flutterRootViewController = [self rootFlutterViewController];
  if (flutterRootViewController) {
    return [[flutterRootViewController pluginRegistry] registrarForPlugin:pluginKey];
  }
  return nil;
}

- (BOOL)hasPlugin:(NSString*)pluginKey {
  FlutterViewController* flutterRootViewController = [self rootFlutterViewController];
  if (flutterRootViewController) {
    return [[flutterRootViewController pluginRegistry] hasPlugin:pluginKey];
  }
  return false;
}

- (NSObject*)valuePublishedByPlugin:(NSString*)pluginKey {
  FlutterViewController* flutterRootViewController = [self rootFlutterViewController];
  if (flutterRootViewController) {
    return [[flutterRootViewController pluginRegistry] valuePublishedByPlugin:pluginKey];
  }
  return nil;
}

#pragma mark - Selectors handling

- (void)addApplicationLifeCycleDelegate:(NSObject<FlutterApplicationLifeCycleDelegate>*)delegate {
  [_lifeCycleDelegate addDelegate:delegate];
}

#pragma mark - UIApplicationDelegate method dynamic implementation

- (BOOL)respondsToSelector:(SEL)selector {
  if ([_lifeCycleDelegate isSelectorAddedDynamically:selector]) {
    return [self delegateRespondsSelectorToPlugins:selector];
  }
  return [super respondsToSelector:selector];
}

- (BOOL)delegateRespondsSelectorToPlugins:(SEL)selector {
  if ([_lifeCycleDelegate hasPluginThatRespondsToSelector:selector]) {
    return [_lifeCycleDelegate respondsToSelector:selector];
  } else {
    return NO;
  }
}

- (id)forwardingTargetForSelector:(SEL)aSelector {
  if ([_lifeCycleDelegate isSelectorAddedDynamically:aSelector]) {
    [self logCapabilityConfigurationWarningIfNeeded:aSelector];
    return _lifeCycleDelegate;
  }
  return [super forwardingTargetForSelector:aSelector];
}

// Mimic the logging from Apple when the capability is not set for the selectors.
// However the difference is that Apple logs these message when the app launches, we only
// log it when the method is invoked. We can possibly also log it when the app launches, but
// it will cause an additional scan over all the plugins.
- (void)logCapabilityConfigurationWarningIfNeeded:(SEL)selector {
  NSArray* backgroundModesArray =
      [[NSBundle mainBundle] objectForInfoDictionaryKey:kUIBackgroundMode];
  NSSet* backgroundModesSet = [[[NSSet alloc] initWithArray:backgroundModesArray] autorelease];
  if (selector == @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)) {
    if (![backgroundModesSet containsObject:kRemoteNotificationCapabitiliy]) {
      NSLog(
          @"You've implemented -[<UIApplicationDelegate> "
          @"application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need "
          @"to add \"remote-notification\" to the list of your supported UIBackgroundModes in your "
          @"Info.plist.");
    }
  } else if (selector == @selector(application:performFetchWithCompletionHandler:)) {
    if (![backgroundModesSet containsObject:kBackgroundFetchCapatibility]) {
      NSLog(@"You've implemented -[<UIApplicationDelegate> "
            @"application:performFetchWithCompletionHandler:], but you still need to add \"fetch\" "
            @"to the list of your supported UIBackgroundModes in your Info.plist.");
    }
  }
}

#pragma mark - State Restoration

- (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder {
  [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
  return YES;
}

- (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder {
  int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
  return self.lastAppModificationTime == stateDate;
}

- (BOOL)application:(UIApplication*)application shouldSaveSecureApplicationState:(NSCoder*)coder {
  [coder encodeInt64:self.lastAppModificationTime forKey:kRestorationStateAppModificationKey];
  return YES;
}

- (BOOL)application:(UIApplication*)application
    shouldRestoreSecureApplicationState:(NSCoder*)coder {
  int64_t stateDate = [coder decodeInt64ForKey:kRestorationStateAppModificationKey];
  return self.lastAppModificationTime == stateDate;
}

- (int64_t)lastAppModificationTime {
  NSDate* fileDate;
  NSError* error = nil;
  [[[NSBundle mainBundle] executableURL] getResourceValue:&fileDate
                                                   forKey:NSURLContentModificationDateKey
                                                    error:&error];
  NSAssert(error == nil, @"Cannot obtain modification date of main bundle: %@", error);
  return [fileDate timeIntervalSince1970];
}

@end
