//
//  DONativeSync.h
//  DOCore
//
//  Created by Ben Dolman on 7/11/14.
//
//

#import <DOCore/DOSync.h>
#import <DOCore/DOSyncState.h>
@class DOJournalPackageFile;
@class DOWebClient;

/**
 * Recommended values for the pollInterval property
 */
static const NSTimeInterval DONativeSyncPollIntervalShort = 15.0;
static const NSTimeInterval DONativeSyncPollIntervalDefault = 30.0;
static const NSTimeInterval DONativeSyncPollIntervalLong = 120.0;

@interface DONativeSync : DOSync

/**
 * The time interval between changes feed requests.
 */
@property (assign) NSTimeInterval pollInterval;

@property (assign, readonly) DOSyncState state;
@property (strong, readonly) NSError *error;

@property (copy, readonly) DOWebClient *webClient;

/**
 * Initializes and starts native sync.
 *
 * @param journalPackage The journal file to synchronize with the server
 * @param webClient Client that contains Day One server host and auth information
 * @param journalID The ID of the remote journal to synchronize with
 * @param sessionIdentifer A unique identifier for this native sync instance. This identifier is used for 
 *        local file state and background transfer sessions. During the lifetime of your app session you must
 *        never instantiate more than one DONativeSync instance per identifier (even after invalidation).
 * @param workingDirectory A directory that will be used to store local state files. A subdirectory named after
 *        sessionIdentifier will be created here.
 * @param error If an error occurs during initialization, nil will be returned and error will be set.
 */
- (instancetype)initWithJournalPackage:(DOJournalPackageFile *)journalPackage
                             webClient:(DOWebClient *)webClient
                             journalID:(NSString *)journalID
                     sessionIdentifier:(NSString *)sessionIdentifier
                      workingDirectory:(NSURL *)workingDirectory
                                 error:(NSError **)error;

/**
 * Returns YES if this object is managing the background session with the given identifier. You should call this
 * to determine if you can then call handleEventsForBackgroundURLSession:completionHandler or if the
 * session is managed by some other object.
 *
 * @param identifier The background session identifier
 */
- (BOOL)canHandleEventsForBackgroundURLSession:(NSString *)identifier;

/**
 * Calls the specified completion handler the next time the background session sends a
 * URLSessionDidFinishEventsForBackgroundURLSession message. Only call this after calling
 * canHandleEventsForBackgroundURLSession otherwise your completion handler will never be invoked.
 *
 * @param identifier The background session identifier
 * @param completionHandler The block to call
 */
 - (void)handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler;

/**
 * Immediately begins a call to the changes feed and calls the completion handler when finished.
 *
 * @param completionHandler the block to invoke after the changes feed call completes
 */
- (void)performSyncWithCompletionHandler:(void (^)(DOSyncResult result))completionHandler;

/**
 * Determines whether the receiver can handle a sync notification. This will return YES if
 * the journal specified in the notification matches the one being managed by the receiver.
 *
 * @param userInfo The userInfo dictionary of the remote notification
 */
- (BOOL)canHandleSyncNotification:(NSDictionary *)userInfo;

/**
 * Handles a sync notification. This may or may not trigger a changes feed request depending on the
 * contents of the userInfo dictionary.
 *
 * @param The userInfo dictionary of the remote notification
 * @param completionHandler The block to call once the notification has been handled
 */
- (void)handleSyncNotification:(NSDictionary *)userInfo
             completionHandler:(void (^)(DOSyncResult result))completionHandler;

/**
 * Returns the date of the last successful changes feed call.
 */
- (NSDate *)lastSyncDate;

@end
