/*
 *  Copyright (c) 2009-2021 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 <objc/runtime.h>
#import "NSInvocation+OCMAdditions.h"
#import "NSMethodSignature+OCMAdditions.h"
#import "NSObject+OCMAdditions.h"
#import "OCPartialMockObject.h"
#import "OCMFunctionsPrivate.h"
#import "OCMInvocationStub.h"


@implementation OCPartialMockObject

#pragma mark Initialisers, description, accessors, etc.

- (id)initWithObject:(NSObject *)anObject
{
    if(anObject == nil)
        [NSException raise:NSInvalidArgumentException format:@"Object cannot be nil."];
    if([anObject isProxy])
        [NSException raise:NSInvalidArgumentException format:@"OCMock does not support partially mocking subclasses of NSProxy."];
    Class const class = [self classToSubclassForObject:anObject];
    [super initWithClass:class];
    realObject = [anObject retain];
    [self prepareObjectForInstanceMethodMocking];
    return self;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"OCPartialMockObject(%@)", NSStringFromClass(mockedClass)];
}

- (NSObject *)realObject
{
    return realObject;
}

#pragma mark Helper methods

- (void)assertClassIsSupported:(Class)class
{
    [super assertClassIsSupported:class];
    NSString *classname = NSStringFromClass(class);
    NSString *reason = nil;
    if([classname hasPrefix:@"__NSTagged"] || [classname hasPrefix:@"NSTagged"])
        reason = [NSString stringWithFormat:@"OCMock does not support partially mocking tagged classes; got %@", classname];
    else if([classname hasPrefix:@"__NSCF"])
        reason = [NSString stringWithFormat:@"OCMock does not support partially mocking toll-free bridged classes; got %@", classname];

    if(reason != nil)
        [[NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil] raise];
}

- (Class)classToSubclassForObject:(id)object
{
    if([object observationInfo] != NULL)
    {
        // Special treatment for objects that are observed with KVO. The KVO implementation sets
        // a subclass for such objects and it overrides the -class method to return the original
        // class. If we base our subclass on the KVO subclass, as returned by object_getClass(),
        // crashes will occur. So, we take the real class instead. Unfortunately, this removes
        // any observers set up before.
        NSLog(@"Warning: Creating a partial mock for %@. This object has observers, which will now stop receiving KVO notifications. If you want to receive KVO notifications, create the partial mock first, and then register the observer.", object);
        return [object class];
    }

    return object_getClass(object);
}

#pragma mark Extending/overriding superclass behaviour

- (void)stopMocking
{
    if(realObject != nil)
    {
        Class partialMockClass = object_getClass(realObject);
        OCMSetAssociatedMockForObject(nil, realObject);
        object_setClass(realObject, [self mockedClass]);
        [realObject release];
        realObject = nil;
        OCMDisposeSubclass(partialMockClass);
    }
    [super stopMocking];
}

- (void)addStub:(OCMInvocationStub *)aStub
{
    [super addStub:aStub];
    if(![aStub recordedAsClassMethod])
        [self setupForwarderForSelector:[[aStub recordedInvocation] selector]];
}

- (void)addInvocation:(NSInvocation *)anInvocation
{
    // If the mock invokes a method on the real object we end up here a second time, but because
    // the mock has added the invocation already we do not want to add it again.
    if((invocationFromMock == nil) || ([anInvocation selector] != [invocationFromMock selector]))
        [super addInvocation:anInvocation];
}

- (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation
{
    // In the case of an init that is called on a mock we must return the mock instance and
    // not the realObject if the underlying init returns the realObject because at the call site
    // ARC will have retained the target and the release/retain count must balance. If we return
    // the realObject, then realObject will be over released and the mock will leak. Equally if
    // we are called on the realObject we need to make sure not to return the mock.
    id targetReceivingInit = nil;
    if([anInvocation methodIsInInitFamily])
    {
        targetReceivingInit = [anInvocation target];
        [realObject retain];
    }

    invocationFromMock = anInvocation;
    [anInvocation invokeWithTarget:realObject];
    invocationFromMock = nil;

    if(targetReceivingInit)
    {
        id returnVal;
        [anInvocation getReturnValue:&returnVal];
        if(returnVal == realObject)
        {
            [anInvocation setReturnValue:&self];
            [realObject release];
            [self retain];
        }
#ifndef __clang_analyzer__
        // see #456 for details
        [targetReceivingInit release];
#endif
    }
}


#pragma mark Subclass management

- (void)prepareObjectForInstanceMethodMocking
{
    OCMSetAssociatedMockForObject(self, realObject);

    /* dynamically create a subclass and set it as the class of the object */
    Class subclass = OCMCreateSubclass(mockedClass, realObject);
    object_setClass(realObject, subclass);

    /* point forwardInvocation: of the object to the implementation in the mock */
    Method myForwardMethod = class_getInstanceMethod([self mockObjectClass], @selector(forwardInvocationForRealObject:));
    IMP myForwardIMP = method_getImplementation(myForwardMethod);
    class_addMethod(subclass, @selector(forwardInvocation:), myForwardIMP, method_getTypeEncoding(myForwardMethod));

    /* do the same for forwardingTargetForSelector, remember existing imp with alias selector */
    Method myForwardingTargetMethod = class_getInstanceMethod([self mockObjectClass], @selector(forwardingTargetForSelectorForRealObject:));
    IMP myForwardingTargetIMP = method_getImplementation(myForwardingTargetMethod);
    IMP originalForwardingTargetIMP = [mockedClass instanceMethodForSelector:@selector(forwardingTargetForSelector:)];
    class_addMethod(subclass, @selector(forwardingTargetForSelector:), myForwardingTargetIMP, method_getTypeEncoding(myForwardingTargetMethod));
    class_addMethod(subclass, @selector(ocmock_replaced_forwardingTargetForSelector:), originalForwardingTargetIMP, method_getTypeEncoding(myForwardingTargetMethod));

    /* We also override the -class method to return the original class */
    Method myObjectClassMethod = class_getInstanceMethod([self mockObjectClass], @selector(classForRealObject));
    const char *objectClassTypes = method_getTypeEncoding(myObjectClassMethod);
    IMP myObjectClassImp = method_getImplementation(myObjectClassMethod);
    class_addMethod(subclass, @selector(class), myObjectClassImp, objectClassTypes);

    /* Adding forwarder for most instance methods to allow for verify after run */
    NSArray *methodsNotToForward = @[ @"class", @"forwardingTargetForSelector:", @"methodSignatureForSelector:", @"forwardInvocation:",
        @"allowsWeakReference", @"retainWeakReference", @"isBlock", @"retainCount", @"retain", @"release", @"autorelease", @".cxx_construct", @".cxx_destruct" ];
    void (^setupForwarderFiltered)(Class, SEL) = ^(Class cls, SEL sel) {
        if(OCMIsAppleBaseClass(cls) || OCMIsApplePrivateMethod(cls, sel))
            return;
        if([methodsNotToForward containsObject:NSStringFromSelector(sel)])
            return;
        @try
        {
            [self setupForwarderForSelector:sel];
        }
        @catch(NSException *e)
        {
            // ignore for now
        }
    };
    [NSObject enumerateMethodsInClass:mockedClass usingBlock:setupForwarderFiltered];
}

- (void)setupForwarderForSelector:(SEL)sel
{
    SEL aliasSelector = OCMAliasForOriginalSelector(sel);
    if(class_getInstanceMethod(object_getClass(realObject), aliasSelector) != NULL)
        return;

    Method originalMethod = class_getInstanceMethod(mockedClass, sel);
    /* Might be NULL if the selector is forwarded to another class */
    IMP originalIMP = (originalMethod != NULL) ? method_getImplementation(originalMethod) : NULL;
    const char *types = (originalMethod != NULL) ? method_getTypeEncoding(originalMethod) : NULL;
    // TODO: check the fallback implementation is actually sufficient
    if(types == NULL)
        types = ([[mockedClass instanceMethodSignatureForSelector:sel] fullObjCTypes]);

    Class subclass = object_getClass([self realObject]);
    IMP forwarderIMP = [mockedClass instanceMethodForwarderForSelector:sel];
    class_replaceMethod(subclass, sel, forwarderIMP, types);
    class_addMethod(subclass, aliasSelector, originalIMP, types);
}


// Implementation of the -class method; return the Class that was reported with [realObject class] prior to mocking
- (Class)classForRealObject
{
    // in here "self" is a reference to the real object, not the mock
    OCPartialMockObject *mock = OCMGetAssociatedMockForObject(self);
    if(mock == nil)
        [NSException raise:NSInternalInconsistencyException format:@"No partial mock for object %p", self];
    return [mock mockedClass];
}


- (id)forwardingTargetForSelectorForRealObject:(SEL)sel
{
    // in here "self" is a reference to the real object, not the mock
    OCPartialMockObject *mock = OCMGetAssociatedMockForObject(self);
    if(mock == nil)
        [NSException raise:NSInternalInconsistencyException format:@"No partial mock for object %p", self];
    if([mock handleSelector:sel])
        return self;

    return [self ocmock_replaced_forwardingTargetForSelector:sel];
}

//  Make the compiler happy in -forwardingTargetForSelectorForRealObject: because it can't find the message…
- (id)ocmock_replaced_forwardingTargetForSelector:(SEL)sel
{
    return nil;
}


- (void)forwardInvocationForRealObject:(NSInvocation *)anInvocation
{
    // in here "self" is a reference to the real object, not the mock
    OCPartialMockObject *mock = OCMGetAssociatedMockForObject(self);
    if(mock == nil)
        [NSException raise:NSInternalInconsistencyException format:@"No partial mock for object %p", self];

    if([mock handleInvocation:anInvocation] == NO)
    {
        [anInvocation setSelector:OCMAliasForOriginalSelector([anInvocation selector])];
        [anInvocation invoke];
    }
}


#pragma mark Verification handling

- (NSString *)descriptionForVerificationFailureWithMatcher:(OCMInvocationMatcher *)matcher quantifier:(OCMQuantifier *)quantifier invocationCount:(NSUInteger)count
{
    SEL matcherSel = [[matcher recordedInvocation] selector];
    __block BOOL stubbingMightHelp = NO;
    [NSObject enumerateMethodsInClass:mockedClass usingBlock:^(Class cls, SEL sel) {
        if(sel == matcherSel)
            stubbingMightHelp = OCMIsAppleBaseClass(cls) || OCMIsApplePrivateMethod(cls, sel);
    }];

    NSString *description = [super descriptionForVerificationFailureWithMatcher:matcher quantifier:quantifier invocationCount:count];
    if(stubbingMightHelp)
    {
        description = [description stringByAppendingFormat:@" Adding a stub for the method may resolve the issue, e.g. `OCMStub([mockObject %@]).andForwardToRealObject()`", [matcher description]];
    }
    return description;
}


@end
