// 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/macos/framework/Headers/FlutterAppLifecycleDelegate.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterAppLifecycleDelegate_Internal.h"

#include <AppKit/AppKit.h>
#include <AppKit/NSApplication.h>
#include <Foundation/Foundation.h>
#include <objc/message.h>

#include "flutter/fml/logging.h"
#include "flutter/fml/paths.h"

@implementation FlutterAppLifecycleRegistrar {
  NSMutableArray* _notificationUnsubscribers;
}

- (void)addObserverFor:(NSString*)name selector:(SEL)selector {
  [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
  __block NSObject* blockSelf = self;
  dispatch_block_t unsubscribe = ^{
    [[NSNotificationCenter defaultCenter] removeObserver:blockSelf name:name object:nil];
  };
  [_notificationUnsubscribers addObject:[unsubscribe copy]];
}

- (instancetype)init {
  if (self = [super init]) {
    _notificationUnsubscribers = [[NSMutableArray alloc] init];

// Using a macro to avoid errors where the notification doesn't match the
// selector.
#ifdef OBSERVE_NOTIFICATION
#error OBSERVE_NOTIFICATION ALREADY DEFINED!
#else
#define OBSERVE_NOTIFICATION(SELECTOR) \
  [self addObserverFor:NSApplication##SELECTOR##Notification selector:@selector(handle##SELECTOR:)]
#endif

    OBSERVE_NOTIFICATION(WillFinishLaunching);
    OBSERVE_NOTIFICATION(DidFinishLaunching);
    OBSERVE_NOTIFICATION(WillBecomeActive);
    OBSERVE_NOTIFICATION(DidBecomeActive);
    OBSERVE_NOTIFICATION(WillResignActive);
    OBSERVE_NOTIFICATION(DidResignActive);
    OBSERVE_NOTIFICATION(WillTerminate);
    OBSERVE_NOTIFICATION(WillHide);
    OBSERVE_NOTIFICATION(DidHide);
    OBSERVE_NOTIFICATION(WillUnhide);
    OBSERVE_NOTIFICATION(DidUnhide);
    OBSERVE_NOTIFICATION(DidChangeScreenParameters);
    OBSERVE_NOTIFICATION(DidChangeOcclusionState);

#undef OBSERVE_NOTIFICATION

    _delegates = [NSPointerArray weakObjectsPointerArray];
  }
  return self;
}

- (void)dealloc {
  for (dispatch_block_t unsubscribe in _notificationUnsubscribers) {
    unsubscribe();
  }
  [_notificationUnsubscribers removeAllObjects];
  _delegates = nil;
  _notificationUnsubscribers = nil;
}

static BOOL IsPowerOfTwo(NSUInteger x) {
  return x != 0 && (x & (x - 1)) == 0;
}

- (void)addDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
  [_delegates addPointer:(__bridge void*)delegate];
  if (IsPowerOfTwo([_delegates count])) {
    [_delegates compact];
  }
}

- (void)removeDelegate:(NSObject<FlutterAppLifecycleDelegate>*)delegate {
  NSUInteger index = [[_delegates allObjects] indexOfObject:delegate];
  if (index != NSNotFound) {
    [_delegates removePointerAtIndex:index];
  }
}

// This isn't done via performSelector because that can cause leaks due to the
// selector not being known. Using a macro to avoid mismatch errors between the
// notification and the selector.
#ifdef DISTRIBUTE_NOTIFICATION
#error DISTRIBUTE_NOTIFICATION ALREADY DEFINED!
#else
#define DISTRIBUTE_NOTIFICATION(SELECTOR)                                  \
  -(void)handle##SELECTOR : (NSNotification*)notification {                \
    for (NSObject<FlutterAppLifecycleDelegate> * delegate in _delegates) { \
      if ([delegate respondsToSelector:@selector(handle##SELECTOR:)]) {    \
        [delegate handle##SELECTOR:notification];                          \
      }                                                                    \
    }                                                                      \
  }
#endif

DISTRIBUTE_NOTIFICATION(WillFinishLaunching)
DISTRIBUTE_NOTIFICATION(DidFinishLaunching)
DISTRIBUTE_NOTIFICATION(WillBecomeActive)
DISTRIBUTE_NOTIFICATION(DidBecomeActive)
DISTRIBUTE_NOTIFICATION(WillResignActive)
DISTRIBUTE_NOTIFICATION(DidResignActive)
DISTRIBUTE_NOTIFICATION(WillTerminate)
DISTRIBUTE_NOTIFICATION(WillHide)
DISTRIBUTE_NOTIFICATION(WillUnhide)
DISTRIBUTE_NOTIFICATION(DidHide)
DISTRIBUTE_NOTIFICATION(DidUnhide)
DISTRIBUTE_NOTIFICATION(DidChangeScreenParameters)
DISTRIBUTE_NOTIFICATION(DidChangeOcclusionState)

#undef DISTRIBUTE_NOTIFICATION

@end
