/************************************************
 * Copyright (c) Shen Li. All rights reserved.  *
 * http://joyaop.sourceforge.net                *
 * -------------------------------------------- *
 * Distributable under LGPL license.            *
 * See terms of license at gnu.org.             *
 ************************************************/
package net.sf.joyaop.extension.mock;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.jmock.core.AbstractDynamicMock;
import org.jmock.core.Invocation;
import org.jmock.core.LIFOInvocationDispatcher;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Modified from JMock, copyright jmock.org
 *
 * @author Shen Li
 */
public class CglibCoreMock extends AbstractDynamicMock implements MethodInterceptor {
    private Object proxy;

    public CglibCoreMock(Class mockedType, String roleName, Class[] argTypes, Object[] args) {
        super(mockedType, roleName, new LIFOInvocationDispatcher());
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(mockedType);
        enhancer.setCallback(this);
        proxy = enhancer.create(argTypes, args);
    }

    public Object proxy() {
        return proxy;
    }

    public Object intercept(Object thisProxy, Method method, Object[] args, MethodProxy superProxy) throws Throwable {
        if (Modifier.isAbstract(method.getModifiers())) {
            return mockInvocation(new Invocation(thisProxy, method, args));
        } else {
            return superProxy.invokeSuper(proxy, args);
        }
    }
}