/*
 * 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 rewrite.org.apache.myfaces.extensions.scripting.core.reloading;


import rewrite.org.apache.myfaces.extensions.scripting.core.context.WeavingContext;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Generic artifact invocation handler
 * which should be able to cover
 * all interfaceable artifacts which
 * only have reloading logic
 * and can cope with reloading on method level
 * <p/>
 * Note this works only for a minority of the artifacts
 * the reason, most artifacts do not rely on interfaces but
 * on base classes
 *
 * @author Werner Punz
 */
@SuppressWarnings("unused")
public class MethodLevelReloadingHandler extends ReloadingInvocationHandler implements Serializable {

    private static final long serialVersionUID = -3034995032644947216L;

    int _artifactType;

    public MethodLevelReloadingHandler(Object rootObject, int artifactType) {
        _loadedClass = rootObject.getClass();
        _delegate = rootObject;
        _artifactType = artifactType;
    }

    /**
     * outside interface to the invoke method
     * which gets called every time a method
     * is called
     *
     * @param object       the object holding the method
     * @param method       the method
     * @param paramHolders the param holders
     * @return the return value of the operation
     * @throws Throwable in case of an error
     */
    public Object invoke(Object object, Method method, Object[] paramHolders) throws Throwable {
        return reloadInvoke(method, paramHolders);
    }

    /**
     * invoke handler which is triggered
     * by every method call which takes care of the reload
     *
     * @param method       the method to call
     * @param paramHolders the params
     * @return the return value of the operation
     * @throws InstantiationException    standard throw caused by reflection
     * @throws IllegalAccessException    standard throw caused by reflection
     * @throws java.lang.reflect.InvocationTargetException standard throw caused by reflection
     */

    protected Object reloadInvoke(Method method, Object[] paramHolders) throws InstantiationException, IllegalAccessException, InvocationTargetException {


        if (_delegate == null) {
            //stateless or lost state due to a lifecycle iteration we trigger anew
            _delegate = (WeavingContext.getInstance().reload(_loadedClass)).newInstance();
        } else {
            //if we are stateful only a tainted artifact is reloaded
            _delegate = WeavingContext.getInstance().reload(_delegate, _artifactType);

            //we work our way through all proxies and fetch the class for further reference
            Object delegate = WeavingContext.getDelegateFromProxy(_delegate);
            _loadedClass = delegate.getClass();
        }
        //check for proxies and unproxy them before calling the methods
        //to avoid unnecessary cast problems
        //this is slow on long param lists but it is better
        //to be slow than to have casts an calls in the code
        //for production we can compile the classes anyway and avoid
        //this
        unmapProxies(paramHolders);
        return method.invoke(_delegate, paramHolders);
    }

    /**
     * unmap proxied objects
     *
     * @param objects the objects to be unmapped
     */
    private void unmapProxies(Object[] objects) {
        if (objects == null) return;
        for (int cnt = 0; cnt < objects.length; cnt++) {
            objects[cnt] = WeavingContext.getDelegateFromProxy(objects[cnt]);
        }
    }

    public int getArtifactType() {
        return _artifactType;
    }

    public void setArtifactType(int artifactType) {
        _artifactType = artifactType;
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
    }

}
