//
//  YSRACDynamicSignal.m
//  ReactiveObjC
//
//  Created by Justin Spahr-Summers on 2013-10-10.
//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
//

#import "YSRACDynamicSignal.h"
#import "YSRACEXTScope.h"
#import "YSRACCompoundDisposable.h"
#import "YSRACPassthroughSubscriber.h"
#import "YSRACScheduler+Private.h"
#import "YSRACSubscriber.h"
#import <libkern/OSAtomic.h>

@interface YSRACDynamicSignal ()

// The block to invoke for each subscriber.
@property (nonatomic, copy, readonly) YSRACDisposable * (^didSubscribe)(id<YSRACSubscriber> subscriber);

@end

@implementation YSRACDynamicSignal

#pragma mark Lifecycle

+ (YSRACSignal *)createSignal:(YSRACDisposable * (^)(id<YSRACSubscriber> subscriber))didSubscribe {
	YSRACDynamicSignal *signal = [[self alloc] init];
	signal->_didSubscribe = [didSubscribe copy];
	return [signal setNameWithFormat:@"+createSignal:"];
}

#pragma mark Managing Subscribers

- (YSRACDisposable *)subscribe:(id<YSRACSubscriber>)subscriber {
	NSCParameterAssert(subscriber != nil);

	YSRACCompoundDisposable *disposable = [YSRACCompoundDisposable compoundDisposable];
	subscriber = [[YSRACPassthroughSubscriber alloc] initWithSubscriber:subscriber signal:self disposable:disposable];

	if (self.didSubscribe != NULL) {
		YSRACDisposable *schedulingDisposable = [YSRACScheduler.subscriptionScheduler schedule:^{
			YSRACDisposable *innerDisposable = self.didSubscribe(subscriber);
			[disposable addDisposable:innerDisposable];
		}];

		[disposable addDisposable:schedulingDisposable];
	}
	
	return disposable;
}

@end
