/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "RTCUIApplicationStatusObserver.h"

#if defined(WEBRTC_IOS)

#import <UIKit/UIKit.h>

#include "webrtc/rtc_base/checks.h"

@interface RTCUIApplicationStatusObserver ()

@property(nonatomic, assign) BOOL initialized;
@property(nonatomic, assign) UIApplicationState state;

@end

@implementation RTCUIApplicationStatusObserver {
  BOOL _initialized;
  dispatch_block_t _initializeBlock;
  dispatch_semaphore_t _waitForInitializeSemaphore;
  UIApplicationState _state;

  id<NSObject> _activeObserver;
  id<NSObject> _backgroundObserver;
}

@synthesize initialized = _initialized;
@synthesize state = _state;

+ (instancetype)sharedInstance {
  static id sharedInstance;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[self alloc] init];
  });

  return sharedInstance;
}

// Method to make sure observers are added and the initialization block is
// scheduled to run on the main queue.
+ (void)prepareForUse {
  __unused RTCUIApplicationStatusObserver *observer = [self sharedInstance];
}

- (id)init {
  if (self = [super init]) {
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    __weak RTCUIApplicationStatusObserver *weakSelf = self;
    _activeObserver = [center addObserverForName:UIApplicationDidBecomeActiveNotification
                                          object:nil
                                           queue:[NSOperationQueue mainQueue]
                                      usingBlock:^(NSNotification *note) {
                                        weakSelf.state =
                                            [UIApplication sharedApplication].applicationState;
                                      }];

    _backgroundObserver = [center addObserverForName:UIApplicationDidEnterBackgroundNotification
                                              object:nil
                                               queue:[NSOperationQueue mainQueue]
                                          usingBlock:^(NSNotification *note) {
                                            weakSelf.state =
                                                [UIApplication sharedApplication].applicationState;
                                          }];

    _waitForInitializeSemaphore = dispatch_semaphore_create(1);
    _initialized = NO;
    _initializeBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
      weakSelf.state = [UIApplication sharedApplication].applicationState;
      weakSelf.initialized = YES;
    });

    dispatch_async(dispatch_get_main_queue(), _initializeBlock);
  }

  return self;
}

- (void)dealloc {
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center removeObserver:_activeObserver];
  [center removeObserver:_backgroundObserver];
}

- (BOOL)isApplicationActive {
  // NOTE: The function `dispatch_block_wait` can only legally be called once.
  // Because of this, if several threads call the `isApplicationActive` method before
  // the `_initializeBlock` has been executed, instead of multiple threads calling
  // `dispatch_block_wait`, the other threads need to wait for the first waiting thread
  // instead.
  if (!_initialized) {
    dispatch_semaphore_wait(_waitForInitializeSemaphore, DISPATCH_TIME_FOREVER);
    if (!_initialized) {
      long ret = dispatch_block_wait(_initializeBlock,
                                     dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC));
      RTC_DCHECK_EQ(ret, 0);
    }
    dispatch_semaphore_signal(_waitForInitializeSemaphore);
  }
  return _state == UIApplicationStateActive;
}

@end

#endif  // WEBRTC_IOS
