package org.apache.commons.digester3;

/*
 * 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.
 */

import static java.lang.System.arraycopy;
import static java.lang.String.format;
import static org.apache.commons.beanutils.ConstructorUtils.getAccessibleConstructor;
import static org.apache.commons.beanutils.ConvertUtils.convert;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * Rule implementation that creates a new object and pushes it onto the object stack. When the element is complete, the
 * object will be popped
 */
public class ObjectCreateRule
    extends Rule
{
    private static class DeferredConstructionCallback implements MethodInterceptor
    {
        Constructor<?> constructor;
        Object[] constructorArgs;
        ArrayList<RecordedInvocation> invocations = new ArrayList<RecordedInvocation>();
        Object delegate;

        DeferredConstructionCallback( Constructor<?> constructor, Object[] constructorArgs )
        {
            this.constructor = constructor;
            this.constructorArgs = constructorArgs;
        }

        public Object intercept( Object obj, Method method, Object[] args, MethodProxy proxy )
            throws Throwable
        {
            boolean hasDelegate = delegate != null;
            if ( !hasDelegate )
            {
                invocations.add( new RecordedInvocation( method, args ) );
            }
            if ( hasDelegate ) {
                return proxy.invoke( delegate, args );
            }
            return proxy.invokeSuper( obj, args );
        }

        void establishDelegate()
            throws Exception
        {
            convertTo( constructor.getParameterTypes(), constructorArgs );
            delegate = constructor.newInstance( constructorArgs );
            for ( RecordedInvocation invocation : invocations )
            {
                invocation.getInvokedMethod().invoke( delegate, invocation.getArguments() );
            }
            constructor = null;
            constructorArgs = null;
            invocations = null;
        }
    }

    private static class ProxyManager
    {
        private final Class<?> clazz;
        private final Constructor<?> constructor;
        private final Object[] templateConstructorArguments;
        private final Digester digester;
        private final boolean hasDefaultConstructor;
        private Factory factory;

        ProxyManager( Class<?> clazz, Constructor<?> constructor, Object[] constructorArguments, Digester digester )
        {
            this.clazz = clazz;
            hasDefaultConstructor = getAccessibleConstructor(clazz, new Class[0]) != null;
            this.constructor = constructor;
            Class<?>[] argTypes = constructor.getParameterTypes();
            templateConstructorArguments = new Object[argTypes.length];
            if ( constructorArguments == null )
            {
                for ( int i = 0; i < templateConstructorArguments.length; i++ )
                {
                    if ( argTypes[i].equals(boolean.class) )
                    {
                        templateConstructorArguments[i] = Boolean.FALSE;
                        continue;
                    }
                    if ( argTypes[i].isPrimitive() )
                    {
                        templateConstructorArguments[i] = convert("0", argTypes[i]);
                        continue;
                    }
                    templateConstructorArguments[i] = null;
                }
            }
            else
            {
                if ( constructorArguments.length != argTypes.length )
                {
                    throw new IllegalArgumentException(
                        format( "wrong number of constructor arguments specified: %s instead of %s",
                        constructorArguments.length, argTypes.length ) );
                }
                arraycopy( constructorArguments, 0, templateConstructorArguments, 0, constructorArguments.length );
            }
            convertTo( argTypes, templateConstructorArguments );
            this.digester = digester;
        }

        Object createProxy()
        {
            Object[] constructorArguments = new Object[templateConstructorArguments.length];
            arraycopy( templateConstructorArguments, 0, constructorArguments, 0, constructorArguments.length );
            digester.pushParams( constructorArguments );

            DeferredConstructionCallback callback = new DeferredConstructionCallback(constructor, constructorArguments);

            Object result;

            if ( factory == null )
            {
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass( clazz );
                enhancer.setCallback( callback );
                enhancer.setClassLoader( digester.getClassLoader() );
                enhancer.setInterceptDuringConstruction(false);
                if ( hasDefaultConstructor )
                {
                    result = enhancer.create();
                }
                else
                {
                    result = enhancer.create( constructor.getParameterTypes(), constructorArguments );
                }
                factory = (Factory) result;
                return result;
            }

            if ( hasDefaultConstructor )
            {
                result = factory.newInstance( callback );
            }
            else
            {
                result = factory.newInstance( constructor.getParameterTypes(),
                    constructorArguments, new Callback[] { callback } );
            }
            return result;
        }

        void finalize( Object proxy ) throws Exception
        {
            digester.popParams();
            ( ( DeferredConstructionCallback ) ( (Factory) proxy).getCallback( 0 ) ).establishDelegate();
        }
    }

    // ----------------------------------------------------------- Constructors

    /**
     * Construct an object create rule with the specified class name.
     *
     * @param className Java class name of the object to be created
     */
    public ObjectCreateRule( String className )
    {
        this( className, (String) null );
    }

    /**
     * Construct an object create rule with the specified class.
     *
     * @param clazz Java class name of the object to be created
     */
    public ObjectCreateRule( Class<?> clazz )
    {
        this( clazz.getName(), (String) null );
        this.clazz = clazz;
    }

    /**
     * Construct an object create rule with the specified class name and an optional attribute name containing an
     * override.
     *
     * @param className Java class name of the object to be created
     * @param attributeName Attribute name which, if present, contains an override of the class name to create
     */
    public ObjectCreateRule( String className, String attributeName )
    {
        this.className = className;
        this.attributeName = attributeName;
    }

    /**
     * Construct an object create rule with the specified class and an optional attribute name containing an override.
     *
     * @param attributeName Attribute name which, if present, contains an
     * @param clazz Java class name of the object to be created override of the class name to create
     */
    public ObjectCreateRule( String attributeName, Class<?> clazz )
    {
        this( clazz.getName(), attributeName );
        this.clazz = clazz;
    }

    // ----------------------------------------------------- Instance Variables

    /**
     * The attribute containing an override class name if it is present.
     */
    protected String attributeName = null;

    /**
     * The Java class of the object to be created.
     */
    protected Class<?> clazz = null;

    /**
     * The Java class name of the object to be created.
     */
    protected String className = null;

    /**
     * The constructor argument types.
     *
     * @since 3.2
     */
    private Class<?>[] constructorArgumentTypes;

    /**
     * The explictly specified default constructor arguments which may be overridden by CallParamRules.
     *
     * @since 3.2
     */
    private Object[] defaultConstructorArguments;

    /**
     * Helper object for managing proxies.
     *
     * @since 3.2
     */
    private ProxyManager proxyManager;

    // --------------------------------------------------------- Public Methods

    /**
     * Allows users to specify constructor argument types.
     *
     * @since 3.2
     */
    public void setConstructorArgumentTypes( Class<?>... constructorArgumentTypes )
    {
        if ( constructorArgumentTypes == null )
        {
            throw new IllegalArgumentException( "Parameter 'constructorArgumentTypes' must not be null" );
        }

        this.constructorArgumentTypes = constructorArgumentTypes;
    }

    /**
     * Allows users to specify default constructor arguments.  If a default/no-arg constructor is not available
     * for the target class, these arguments will be used to create the proxy object.  For any argument
     * not supplied by a {@link CallParamRule}, the corresponding item from this array will be used
     * to construct the final object as well.
     *
     * @since 3.2
     */
    public void setDefaultConstructorArguments( Object... constructorArguments )
    {
        if ( constructorArguments == null )
        {
            throw new IllegalArgumentException( "Parameter 'constructorArguments' must not be null" );
        }

        this.defaultConstructorArguments = constructorArguments;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void begin( String namespace, String name, Attributes attributes )
        throws Exception
    {
        Class<?> clazz = this.clazz;

        if ( clazz == null )
        {
            // Identify the name of the class to instantiate
            String realClassName = className;
            if ( attributeName != null )
            {
                String value = attributes.getValue( attributeName );
                if ( value != null )
                {
                    realClassName = value;
                }
            }
            if ( getDigester().getLogger().isDebugEnabled() )
            {
                getDigester().getLogger().debug( format( "[ObjectCreateRule]{%s} New '%s'",
                                                         getDigester().getMatch(),
                                                         realClassName ) );
            }

            // Instantiate the new object and push it on the context stack
            clazz = getDigester().getClassLoader().loadClass( realClassName );
        }
        Object instance;
        if ( constructorArgumentTypes == null || constructorArgumentTypes.length == 0 )
        {
            if ( getDigester().getLogger().isDebugEnabled() )
            {
                getDigester().getLogger().debug( format( "[ObjectCreateRule]{%s} New '%s' using default empty constructor",
                                                         getDigester().getMatch(),
                                                         clazz.getName() ) );
            }

            instance = clazz.newInstance();
        }
        else
        {
            if ( proxyManager == null )
            {
                Constructor<?> constructor = getAccessibleConstructor( clazz, constructorArgumentTypes );

                if ( constructor == null )
                {
                    throw new SAXException( format( "[ObjectCreateRule]{%s} Class '%s' does not have a construcor with types %s",
                                                    getDigester().getMatch(),
                                                    clazz.getName(),
                                                    Arrays.toString( constructorArgumentTypes ) ) );
                }
                proxyManager = new ProxyManager(clazz, constructor, defaultConstructorArguments, getDigester());
            }
            instance = proxyManager.createProxy();
        }
        getDigester().push( instance );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void end( String namespace, String name )
        throws Exception
    {
        Object top = getDigester().pop();

        if ( proxyManager != null )
        {
            proxyManager.finalize(top);
        }

        if ( getDigester().getLogger().isDebugEnabled() )
        {
            getDigester().getLogger().debug( format( "[ObjectCreateRule]{%s} Pop '%s'",
                                                     getDigester().getMatch(),
                                                     top.getClass().getName() ) );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
        return format( "ObjectCreateRule[className=%s, attributeName=%s]", className, attributeName );
    }

    private static void convertTo( Class<?>[] types, Object[] array )
    {
        if ( array.length != types.length )
        {
            throw new IllegalArgumentException();
        }
        // this piece of code is adapted from CallMethodRule
        for ( int i = 0; i < array.length; i++ )
        {
            // convert nulls and convert stringy parameters for non-stringy param types
            if ( array[i] == null
                    || ( array[i] instanceof String && !String.class.isAssignableFrom( types[i] ) ) )
            {
                array[i] = convert( (String) array[i], types[i] );
            }
        }
    }

}
