//
//    ____                _           _ _           ____  ____  _  __
//   |  _ \ _ __ _____  _(_)_ __ ___ (_) |_ _   _  / ___||  _ \| |/ /
//   | |_) | '__/ _ \ \/ / | '_ ` _ \| | __| | | | \___ \| | | | ' /
//   |  __/| | | (_) >  <| | | | | | | | |_| |_| |  ___) | |_| | . \
//   |_|   |_|  \___/_/\_\_|_| |_| |_|_|\__|\__, | |____/|____/|_|\_\
//                                          |___/
//
//   Copyright © 2017 Estimote. All rights reserved.
//

#import <Foundation/Foundation.h>

@class EPXCloudCredentials;
@class EPXProximityZone;
@class EPXProximityObserverConfiguration;

NS_ASSUME_NONNULL_BEGIN

FOUNDATION_EXPORT NSString * const EPXProximityObserverErrorDomain;

/**
 Possible errors invoked with Proximity Observer's error block.
 */
typedef NS_ENUM(NSUInteger, EPXProximityObserverError) {
    /* Unknown error probably due to a bug. If you're getting errors with this code please report it on
     * https://forums.estimote.com, using contact@estimote.com or filing an issue on Github. */
    EPXProximityObserverErrorUnknown = 0,

    /* Fetching attachments from Cloud failed. */
    EPXProximityObserverErrorFetchingAttachmentsFailed,

    /* Bluetooth is unsupported on this iOS device. */
    EPXProximityObserverErrorBluetoothUnsupported,

    /* Bluetooth is turned off. */
    EPXProximityObserverErrorBluetoothOff,

    /* Couldn't use motion detection. */
    EPXProximityObserverErrorMotionDetectionFailed,
};

/**
 Observes and reports proximity of Estimote devices. 
 Uses Estimote Monitoring under the hood. Encapsulates it under tag-based beacon identification and callback blocks.
 */
@interface EPXProximityObserver : NSObject

/**
 Init is disabled for this class.
 */
- (instancetype)init NS_UNAVAILABLE;

/**
 New is disabled for this class.
 */
+ (instancetype)new NS_UNAVAILABLE;

/**
 Convenience initializer. Calls designated initializer with default configuration.
 @param credentials Cloud Credentials object used to authorize requests sent to Estimote Cloud.
 @param errorBlock Block invoked whenever error occurs. The parameter is an NSError object, with
                   domain equal to EPXProximityObserverErrorDomain and code from EPXProximityObserverError enum.
 */
- (instancetype)initWithCredentials:(EPXCloudCredentials *)credentials
                         errorBlock:(void (^)(NSError *error))errorBlock;

/**
 Designated initializer.
 @param credentials Cloud Credentials object used to authorize requests sent to Estimote Cloud.
 @param configuration Proximity observer configuration that can be used for Proximity Observer's behaviour customization.
 @param errorBlock Block invoked whenever error occurs. The parameter is an NSError object, with
                   domain equal to EPXProximityObserverErrorDomain and code from EPXProximityObserverError enum.
 */
- (instancetype)initWithCredentials:(EPXCloudCredentials *)credentials
                      configuration:(EPXProximityObserverConfiguration *)configuration
                         errorBlock:(void (^)(NSError *error))errorBlock;

/**
 Start observing and calling callbacks on provided proximity zones:
 - request device details for all user's devices from Estimote Cloud,
 - start Estimote Monitoring at registered ranges,
 - call registered enter/exit/change blocks when proximity event occurs.

 Subsequent calls of this method cause overwriting previously observed zones.

 Note: at the moment, Proximity SDK supports monitoring only 100 devices per zone. If more devices have their attachments
 matching the key, value defined in the zone, the first 100 are monitored.
 
 @param zones Zones to be observed.
 */
- (void)startObservingZones:(NSArray<EPXProximityZone *> *)zones;

/**
 Stop observing and calling callbacks for all zones that were provided with -startObservingZones:,
 release memory resources allocated for monitoring the zones.

 Subsequent calls of this method (without re-starting observing zones) have the same effect as calling it just once.
 */
- (void)stopObservingZones;

@end

NS_ASSUME_NONNULL_END
