/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file 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.
 */

package org.apache.commons.proxy2.javassist;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import org.apache.commons.proxy2.Interceptor;
import org.apache.commons.proxy2.Invoker;
import org.apache.commons.proxy2.ObjectProvider;
import org.apache.commons.proxy2.ProxyUtils;
import org.apache.commons.proxy2.exception.ProxyFactoryException;
import org.apache.commons.proxy2.impl.AbstractProxyClassGenerator;
import org.apache.commons.proxy2.impl.AbstractSubclassingProxyFactory;
import org.apache.commons.proxy2.impl.ProxyClassCache;

import java.lang.reflect.Method;

public class JavassistProxyFactory extends AbstractSubclassingProxyFactory
{
    //**********************************************************************************************************************
// Fields
//**********************************************************************************************************************

    private static final String GET_METHOD_METHOD_NAME = "_javassistGetMethod";

    private static final ProxyClassCache delegatingProxyClassCache = new ProxyClassCache(
            new DelegatingProxyClassGenerator());
    private static final ProxyClassCache interceptorProxyClassCache = new ProxyClassCache(
            new InterceptorProxyClassGenerator());
    private static final ProxyClassCache invocationHandlerProxyClassCache = new ProxyClassCache(
            new InvokerProxyClassGenerator());

//**********************************************************************************************************************
// Static Methods
//**********************************************************************************************************************

    private static void addGetMethodMethod(CtClass proxyClass) throws CannotCompileException
    {
        final CtMethod method = new CtMethod(JavassistUtils.resolve(Method.class), GET_METHOD_METHOD_NAME,
                JavassistUtils.resolve(new Class[]{String.class, String.class, Class[].class}), proxyClass);
        final String body = "try { return Class.forName($1).getMethod($2, $3); } catch( Exception e ) " +
                "{ throw new RuntimeException(\"Unable to look up method.\", e); }";
        method.setBody(body);
        proxyClass.addMethod(method);
    }

//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************

    public Object createDelegatorProxy(ClassLoader classLoader, ObjectProvider targetProvider,
                                       Class... proxyClasses)
    {
        try
        {
            final Class clazz = delegatingProxyClassCache.getProxyClass(classLoader, proxyClasses);
            return clazz.getConstructor(ObjectProvider.class)
                    .newInstance(targetProvider);
        }
        catch (Exception e)
        {
            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
        }
    }

    public Object createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
                                         Class... proxyClasses)
    {
        try
        {
            final Class clazz = interceptorProxyClassCache.getProxyClass(classLoader, proxyClasses);
            return clazz.getConstructor(Object.class, Interceptor.class)
                    .newInstance(target, interceptor);
        }
        catch (Exception e)
        {
            throw new ProxyFactoryException("Unable to instantiate proxy2 class instance.", e);
        }
    }

    public Object createInvokerProxy(ClassLoader classLoader, Invoker invoker,
                                     Class... proxyClasses)
    {
        try
        {
            final Class clazz = invocationHandlerProxyClassCache.getProxyClass(classLoader, proxyClasses);
            return clazz.getConstructor(Invoker.class)
                    .newInstance(invoker);
        }
        catch (Exception e)
        {
            throw new ProxyFactoryException("Unable to instantiate proxy2 from generated proxy2 class.", e);
        }
    }

//**********************************************************************************************************************
// Inner Classes
//**********************************************************************************************************************

    private static class DelegatingProxyClassGenerator extends AbstractProxyClassGenerator
    {
        public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
        {
            try
            {
                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
                JavassistUtils.addField(ObjectProvider.class, "provider", proxyClass);
                final CtConstructor proxyConstructor = new CtConstructor(
                        JavassistUtils.resolve(new Class[]{ObjectProvider.class}),
                        proxyClass);
                proxyConstructor.setBody("{ this.provider = $1; }");
                proxyClass.addConstructor(proxyConstructor);
                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
                addHashCodeMethod(proxyClass);
                addEqualsMethod(proxyClass);
                final Method[] methods = getImplementationMethods(proxyClasses);
                for (int i = 0; i < methods.length; ++i)
                {
                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
                    {
                        final Method method = methods[i];
                        final CtMethod ctMethod = new CtMethod(JavassistUtils.resolve(method.getReturnType()),
                                method.getName(),
                                JavassistUtils.resolve(method.getParameterTypes()),
                                proxyClass);
                        final String body = "{ return ( $r ) ( ( " + method.getDeclaringClass().getName() +
                                " )provider.getObject() )." +
                                method.getName() + "($$); }";
                        ctMethod.setBody(body);
                        proxyClass.addMethod(ctMethod);
                    }
                }
                return proxyClass.toClass(classLoader);
            }
            catch (CannotCompileException e)
            {
                throw new ProxyFactoryException("Could not compile class.", e);
            }
        }
    }

    private static class InterceptorProxyClassGenerator extends AbstractProxyClassGenerator
    {
        public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
        {
            try
            {
                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
                final Method[] methods = getImplementationMethods(proxyClasses);
                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
                JavassistUtils.addField(Object.class, "target", proxyClass);
                JavassistUtils.addField(Interceptor.class, "interceptor", proxyClass);
                addGetMethodMethod(proxyClass);
                addHashCodeMethod(proxyClass);
                addEqualsMethod(proxyClass);
                final CtConstructor proxyConstructor = new CtConstructor(
                        JavassistUtils.resolve(
                                new Class[]{Object.class, Interceptor.class}),
                        proxyClass);
                proxyConstructor
                        .setBody(
                                "{\n\tthis.target = $1;\n\tthis.interceptor = $2; }");
                proxyClass.addConstructor(proxyConstructor);
                for (int i = 0; i < methods.length; ++i)
                {
                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
                    {
                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
                                methods[i].getName(),
                                JavassistUtils.resolve(methods[i].getParameterTypes()),
                                proxyClass);
                        final Class invocationClass = JavassistInvocation
                                .getMethodInvocationClass(classLoader, methods[i]);

                        final String body = "{\n\t return ( $r ) interceptor.intercept( new " + invocationClass.getName() +
                                "( " + GET_METHOD_METHOD_NAME + "(\"" + methods[i].getDeclaringClass().getName() +
                                "\", \"" + methods[i].getName() + "\", $sig), target, $args ) );\n }";
                        method.setBody(body);
                        proxyClass.addMethod(method);
                    }

                }
                return proxyClass.toClass(classLoader);
            }
            catch (CannotCompileException e)
            {
                throw new ProxyFactoryException("Could not compile class.", e);
            }
        }


    }

    private static void addEqualsMethod(CtClass proxyClass)
            throws CannotCompileException
    {
        final CtMethod equalsMethod = new CtMethod(JavassistUtils.resolve(Boolean.TYPE), "equals",
                JavassistUtils.resolve(new Class[]{Object.class}), proxyClass);
        final String body = "{\n\treturn this == $1;\n}";
        equalsMethod.setBody(body);
        proxyClass.addMethod(equalsMethod);
    }

    private static void addHashCodeMethod(CtClass proxyClass)
            throws CannotCompileException
    {
        final CtMethod hashCodeMethod = new CtMethod(JavassistUtils.resolve(Integer.TYPE), "hashCode",
                new CtClass[0], proxyClass);
        hashCodeMethod.setBody("{\n\treturn System.identityHashCode(this);\n}");
        proxyClass.addMethod(hashCodeMethod);
    }

    private static class InvokerProxyClassGenerator extends AbstractProxyClassGenerator
    {
        public Class generateProxyClass(ClassLoader classLoader, Class[] proxyClasses)
        {
            try
            {
                final CtClass proxyClass = JavassistUtils.createClass(getSuperclass(proxyClasses));
                final Method[] methods = getImplementationMethods(proxyClasses);
                JavassistUtils.addInterfaces(proxyClass, toInterfaces(proxyClasses));
                JavassistUtils.addField(Invoker.class, "invoker", proxyClass);
                final CtConstructor proxyConstructor = new CtConstructor(
                        JavassistUtils.resolve(
                                new Class[]{Invoker.class}),
                        proxyClass);
                proxyConstructor
                        .setBody("{\n\tthis.invoker = $1; }");
                proxyClass.addConstructor(proxyConstructor);
                addGetMethodMethod(proxyClass);
                addHashCodeMethod(proxyClass);
                addEqualsMethod(proxyClass);
                for (int i = 0; i < methods.length; ++i)
                {
                    if (!ProxyUtils.isEqualsMethod(methods[i]) && !ProxyUtils.isHashCode(methods[i]))
                    {
                        final CtMethod method = new CtMethod(JavassistUtils.resolve(methods[i].getReturnType()),
                                methods[i].getName(),
                                JavassistUtils.resolve(methods[i].getParameterTypes()),
                                proxyClass);
                        final String body = "{\n\t return ( $r ) invoker.invoke( this, " + GET_METHOD_METHOD_NAME + "(\"" +
                                methods[i].getDeclaringClass().getName() +
                                "\", \"" + methods[i].getName() + "\", $sig), $args );\n }";
                        method.setBody(body);
                        proxyClass.addMethod(method);
                    }
                }
                return proxyClass.toClass(classLoader);
            }
            catch (CannotCompileException e)
            {
                throw new ProxyFactoryException("Could not compile class.", e);
            }
        }
    }
}
