/*
 *  Copyright (c) 2013-2015 Erik Doernenburg and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use these files except in compliance with the License. You may obtain
 *  a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *  License for the specific language governing permissions and limitations
 *  under the License.
 */

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import <objc/runtime.h>

#pragma mark   Helper classes

@interface InternalObject : NSObject
{
    NSString *_name;
}
@property (nonatomic, strong) NSString *name;
@end

@interface PublicObject : NSObject
{
    InternalObject *_internal;
};
@property (nonatomic, strong) NSString *name;
@end

@implementation InternalObject

@synthesize name = _name;

@end


@implementation PublicObject

@dynamic name;

- (instancetype)initWithInternal:(InternalObject *)internal
{
    self = [super init];
    if (!self)
        return self;

    _internal = internal;
    return self;
}

- (instancetype)init
{
    return [self initWithInternal:[[InternalObject alloc] init]];
}

- (id)forwardingTargetForSelector:(SEL)selector
{
    if (selector == @selector(name) ||
        selector == @selector(setName:))
        return _internal;
    return [super forwardingTargetForSelector:selector];
}

+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)selector
{
    NSMethodSignature *signature = [super instanceMethodSignatureForSelector:selector];
    if (signature)
        return signature;
    else
        return [InternalObject instanceMethodSignatureForSelector:selector];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:selector];
    if (signature)
        return signature;

    return [[self forwardingTargetForSelector:selector] methodSignatureForSelector:selector];
}

- (BOOL)respondsToSelector:(SEL)selector
{
    if ([super respondsToSelector:selector])
        return YES;

    return [[self forwardingTargetForSelector:selector] respondsToSelector:selector];
}

+ (BOOL)instancesRespondToSelector:(SEL)selector
{
    if (class_respondsToSelector(self, selector))
        return YES;

    return [InternalObject instancesRespondToSelector:selector];
}

- (id)valueForUndefinedKey:(NSString *)key
{
    return [_internal valueForKey:key];
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    [_internal setValue:value forKey:key];
}

@end


#pragma mark    Tests


@interface OCMockForwardingTargetTests : XCTestCase

@end


@implementation OCMockForwardingTargetTests

- (void)testNameShouldForwardToInternal
{
    InternalObject *internal = [[InternalObject alloc] init];
    internal.name = @"Internal Object";
    PublicObject *public = [[PublicObject alloc] initWithInternal:internal];
    XCTAssertEqualObjects(@"Internal Object", public.name);
}

- (void)testStubsMethodImplementation
{
    PublicObject *public = [[PublicObject alloc] init];
    id mock = [OCMockObject partialMockForObject:public];

    [[[mock stub] andReturn:@"FOO"] name];
    XCTAssertEqualObjects(@"FOO", [mock name]);
}

@end
