//
//  NSObject+RACDeallocating.m
//  ReactiveCocoa
//
//  Created by Kazuo Koga on 2013/03/15.
//  Copyright (c) 2013 GitHub, Inc. All rights reserved.
//

#import "RACTestObject.h"

#import "NSObject+RACDeallocating.h"
#import "RACCompoundDisposable.h"
#import "RACDisposable.h"
#import "RACSignal+Operations.h"
#import <objc/runtime.h>

@interface RACDeallocSwizzlingTestClass : NSObject
@end

@implementation RACDeallocSwizzlingTestClass

- (void)dealloc {
	// Provide an empty implementation just so we can swizzle it.
}

@end

@interface RACDeallocSwizzlingTestSubclass : RACDeallocSwizzlingTestClass
@end

@implementation RACDeallocSwizzlingTestSubclass
@end

SpecBegin(NSObjectRACDeallocatingSpec)

describe(@"-dealloc swizzling", ^{
	SEL selector = NSSelectorFromString(@"dealloc");

	it(@"should not invoke superclass -dealloc method twice", ^{
		__block NSUInteger superclassDeallocatedCount = 0;
		__block BOOL subclassDeallocated = NO;

		@autoreleasepool {
			RACDeallocSwizzlingTestSubclass *object __attribute__((objc_precise_lifetime)) = [[RACDeallocSwizzlingTestSubclass alloc] init];

			Method oldDeallocMethod = class_getInstanceMethod(RACDeallocSwizzlingTestClass.class, selector);
			void (*oldDealloc)(id, SEL) = (__typeof__(oldDealloc))method_getImplementation(oldDeallocMethod);

			id newDealloc = ^(__unsafe_unretained id self) {
				superclassDeallocatedCount++;
				oldDealloc(self, selector);
			};

			class_replaceMethod(RACDeallocSwizzlingTestClass.class, selector, imp_implementationWithBlock(newDealloc), method_getTypeEncoding(oldDeallocMethod));

			[object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
				subclassDeallocated = YES;
			}]];

			expect(subclassDeallocated).to.beFalsy();
			expect(superclassDeallocatedCount).to.equal(0);
		}

		expect(subclassDeallocated).to.beTruthy();
		expect(superclassDeallocatedCount).to.equal(1);
	});

	it(@"should invoke superclass -dealloc method swizzled in after the subclass", ^{
		__block BOOL superclassDeallocated = NO;
		__block BOOL subclassDeallocated = NO;

		@autoreleasepool {
			RACDeallocSwizzlingTestSubclass *object __attribute__((objc_precise_lifetime)) = [[RACDeallocSwizzlingTestSubclass alloc] init];
			[object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
				subclassDeallocated = YES;
			}]];

			Method oldDeallocMethod = class_getInstanceMethod(RACDeallocSwizzlingTestClass.class, selector);
			void (*oldDealloc)(id, SEL) = (__typeof__(oldDealloc))method_getImplementation(oldDeallocMethod);

			id newDealloc = ^(__unsafe_unretained id self) {
				superclassDeallocated = YES;
				oldDealloc(self, selector);
			};

			class_replaceMethod(RACDeallocSwizzlingTestClass.class, selector, imp_implementationWithBlock(newDealloc), method_getTypeEncoding(oldDeallocMethod));

			expect(subclassDeallocated).to.beFalsy();
			expect(superclassDeallocated).to.beFalsy();
		}

		expect(subclassDeallocated).to.beTruthy();
		expect(superclassDeallocated).to.beTruthy();
	});
});

describe(@"-rac_deallocDisposable", ^{
	it(@"should dispose of the disposable when it is dealloc'd", ^{
		__block BOOL wasDisposed = NO;
		@autoreleasepool {
			NSObject *object __attribute__((objc_precise_lifetime)) = [[NSObject alloc] init];
			[object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
				wasDisposed = YES;
			}]];

			expect(wasDisposed).to.beFalsy();
		}

		expect(wasDisposed).to.beTruthy();
	});

	it(@"should be able to use the object during disposal", ^{
		@autoreleasepool {
			RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init];

			@autoreleasepool {
				object.objectValue = [@"foo" mutableCopy];
			}

			__unsafe_unretained RACTestObject *weakObject = object;

			[object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
				expect(weakObject.objectValue).to.equal(@"foo");
			}]];
		}
	});
});

describe(@"-rac_willDeallocSignal", ^{
	it(@"should complete on dealloc", ^{
		__block BOOL completed = NO;
		@autoreleasepool {
			[[[[RACTestObject alloc] init] rac_willDeallocSignal] subscribeCompleted:^{
				completed = YES;
			}];
		}

		expect(completed).to.beTruthy();
	});

	it(@"should not send anything", ^{
		__block BOOL valueReceived = NO;
		__block BOOL completed = NO;
		@autoreleasepool {
			[[[[RACTestObject alloc] init] rac_willDeallocSignal] subscribeNext:^(id x) {
				valueReceived = YES;
			} completed:^{
				completed = YES;
			}];
		}

		expect(valueReceived).to.beFalsy();
		expect(completed).to.beTruthy();
	});

	it(@"should complete upon subscription if already deallocated", ^{
		__block BOOL deallocated = NO;

		RACSignal *signal;

		@autoreleasepool {
			RACTestObject *object = [[RACTestObject alloc] init];

			signal = [object rac_willDeallocSignal];
			[signal subscribeCompleted:^{
				deallocated = YES;
			}];
		}

		expect(deallocated).to.beTruthy();
		expect([signal waitUntilCompleted:NULL]).to.beTruthy();
	});

	it(@"should complete before the object is invalid", ^{
		__block NSString *objectValue;

		@autoreleasepool {
			RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init];

			@autoreleasepool {
				object.objectValue = [@"foo" mutableCopy];
			}

			__unsafe_unretained RACTestObject *weakObject = object;

			[[object rac_willDeallocSignal] subscribeCompleted:^{
				objectValue = [weakObject.objectValue copy];
			}];
		}

		expect(objectValue).to.equal(@"foo");
	});
});

SpecEnd
