/*
 * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
 * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
 * Copyright (c) 2007, Alin Dreghiciu. All Rights Reserved.
 *
 * Licensed 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.qi4j.runtime.composite;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.qi4j.api.Qi4j;
import org.qi4j.api.composite.Composite;
import org.qi4j.api.composite.CompositeInstance;
import org.qi4j.api.property.StateHolder;
import org.qi4j.api.structure.Layer;
import org.qi4j.api.structure.Module;
import org.qi4j.runtime.structure.ModuleInstance;
import org.qi4j.spi.module.ModuleSpi;

/**
 * InvocationHandler for proxy objects.
 */
public class TransientInstance
    implements CompositeInstance, MixinsInstance
{
    public static TransientInstance compositeInstanceOf( Composite composite )
    {
        InvocationHandler handler = Proxy.getInvocationHandler( composite );
        return (TransientInstance) handler;
    }

    private final Composite proxy;
    protected final Object[] mixins;
    protected StateHolder state;
    protected final CompositeModel compositeModel;
    private final ModuleSpi moduleInstance;

    public TransientInstance( CompositeModel compositeModel,
                              ModuleSpi moduleInstance,
                              Object[] mixins,
                              StateHolder state
    )
    {
        this.compositeModel = compositeModel;
        this.moduleInstance = moduleInstance;
        this.mixins = mixins;
        this.state = state;

        proxy = compositeModel.newProxy( this );
    }

    @Override
    public Object invoke( Object proxy, Method method, Object[] args )
        throws Throwable
    {
        return compositeModel.invoke( this, proxy, method, args, moduleInstance );
    }

    @Override
    @SuppressWarnings( "unchecked" )
    public <T> T proxy()
    {
        return (T) proxy;
    }

    @Override
    public <T> T newProxy( Class<T> mixinType )
        throws IllegalArgumentException
    {
        return compositeModel.newProxy( this, mixinType );
    }

    @Override
    public Object invokeComposite( Method method, Object[] args )
        throws Throwable
    {
        return compositeModel.invoke( this, proxy, method, args, moduleInstance );
    }

    @Override
    public CompositeModel descriptor()
    {
        return compositeModel;
    }

    @Override
    public <T> T metaInfo( Class<T> infoType )
    {
        return compositeModel.metaInfo( infoType );
    }

    @Override
    public Iterable<Class<?>> types()
    {
        return compositeModel.types();
    }

    @Override
    public Module module()
    {
        return moduleInstance;
    }

    public Layer layer()
    {
        return ( (ModuleInstance) moduleInstance ).layerInstance();
    }

    @Override
    public StateHolder state()
    {
        return state;
    }

    @Override
    public Object invoke( Object composite, Object[] params, CompositeMethodInstance methodInstance )
        throws Throwable
    {
        Object mixin = methodInstance.getMixinFrom( mixins );
        return methodInstance.invoke( proxy, params, mixin );
    }

    @Override
    public Object invokeObject( Object proxy, Object[] args, Method method )
        throws Throwable
    {
        return method.invoke( this, args );
    }

    @Override
    public boolean equals( Object o )
    {
        if( o == null )
        {
            return false;
        }
        if( !Proxy.isProxyClass( o.getClass() ) )
        {
            return false;
        }
        TransientInstance other = (TransientInstance) Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( (Composite) o );
        if( other.mixins.length != mixins.length )
        {
            return false;
        }

        for( int i = 0; i < mixins.length; i++ )
        {
            if( !mixins[ i ].equals( other.mixins[ i ] ) )
            {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode()
    {
        int hashCode = 0;
        for( Object mixin : mixins )
        {
            hashCode = hashCode * 31 + mixin.hashCode();
        }
        return hashCode;
    }

    @Override
    public String toString()
    {
        StringBuilder buffer = new StringBuilder();
        boolean first = true;
        for( Object mixin : mixins )
        {
            try
            {
                if( mixin != null )  // Can happen during construction of incorrect composites, during exception creation.
                {
                    Class<?> type = mixin.getClass();
                    Method toStringMethod = type.getMethod( "toString" );
                    Class<?> declaringClass = toStringMethod.getDeclaringClass();
                    if( !declaringClass.equals( Object.class ) )
                    {
                        if( !first )
                        {
                            buffer.append( ", " );
                        }
                        first = false;
                        buffer.append( mixin.toString() );
                    }
                }
            }
            catch( NoSuchMethodException e )
            {
                // Can not happen??
                e.printStackTrace();
            }
        }
        if( first )
        {
            String modelTypeName = compositeModel.getClass().getSimpleName();
            String metaTypeModel = modelTypeName.substring( 0, modelTypeName.length() - 5 );
            return metaTypeModel + "Instance{" +
                   "mixins=" + ( mixins == null ? null : Arrays.asList( mixins ) ) +
                   ", state=" + state +
                   ", compositeModel=" + compositeModel +
                   ", module=" + moduleInstance +
                   '}';
        }
        return buffer.toString();
    }
}