//
//  CSFuture.h
//  iPartition
//
//  Created by Chris Suter on 22/05/13.
//  Copyright (c) 2013 Coriolis Systems Limited. All rights reserved.
//

#import <Foundation/Foundation.h>

@class CSFuture;

@protocol CSFutureDelegate

- (void)didResolveFuture:(CSFuture *)future;

@end

@interface CSFuture : NSObject {
  NSMutableArray *_delegates;
}

@property (readonly) bool valid;
@property (readonly) id value;

- (void)addDelegate:(id<CSFutureDelegate>)delegate;
- (void)removeDelegate:(id<CSFutureDelegate>)delegate;

- (void)wait;
- (void)waitUntilDate:(NSDate *)date;

@end

@interface CSFuture (Abstract)

- (id)primitiveValue;

@end

@interface CSValueFuture : CSFuture <CSFutureDelegate> {
  id _value;
  bool _valid;
  CSValueFuture *_otherFuture;
}

+ (id)future;
- (void)takeValueFrom:(CSValueFuture *)other;

@end

// Stores an error.  Returns nil for no error
@interface CSErrorFuture : CSValueFuture

- (NSError *)error;
- (void)setError:(NSError *)error;
- (bool)succeeded;

@end

/* The value is that of the first child future that has a non-nil
   value, or nil if they all return nil. */
@interface CSCompoundFuture : CSFuture <CSFutureDelegate> {
  NSArray *_children;
  id _value;
  NSUInteger _waiting;
}

+ (CSCompoundFuture *)futureWithChildren:(NSArray *)children;

@end
