package org.apache.myfaces.extensions.scripting.facelet.support;

import org.apache.myfaces.extensions.scripting.core.util.ReflectUtil;

import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.Metadata;
import javax.faces.view.facelets.MetadataTarget;
import javax.faces.view.facelets.TagAttribute;
import java.lang.reflect.Method;

/**
 * We have to introduce a BeanPropertyTagRule
 * which calls the setter of a given component
 * on a weaker base than the original facelets component
 * property tag rule does.
 * By not enforcing a strict per object/class policy on calling
 * the setter we are able to reload the classes on the fly
 * <p/>
 * the original approach was to cache the classes, and then
 * call the invoke method on the existing class
 * if we now exchange the classes we have a problem...
 * By making the invocation of the method independend from the underlying
 * class (sort of calling an invokedynamic) we can bypass this problem
 * on facelets level.
 */
public class InvokeDynamicBeanPropertyTagRule {
    public final static InvokeDynamicBeanPropertyTagRule Instance = new InvokeDynamicBeanPropertyTagRule();

    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta) {
        Method m = meta.getWriteMethod(name);

        // if the property is writable
        if (m != null) {
            if (attribute.isLiteral()) {
                return new LiteralPropertyMetadata(m, attribute);
            } else {
                return new DynamicPropertyMetadata(m, attribute);
            }
        }

        return null;
    }

    final static class LiteralPropertyMetadata extends Metadata {

        private final Method method;

        private final TagAttribute attribute;

        private Object[] value;

        public LiteralPropertyMetadata(Method method, TagAttribute attribute) {
            this.method = method;
            this.attribute = attribute;
        }

        public void applyMetadata(FaceletContext ctx, Object instance) {
            if (value == null) {
                String str = this.attribute.getValue();
                value = new Object[]{ctx.getExpressionFactory().coerceToType(str, method.getParameterTypes()[0])};
            }
            //What we do here is simply to call an invoke dynamic on the method with the same name
            //but on the new instance of, that way we can bypass class problems
            //because the method reference has stored the old class in our case
            ReflectUtil.executeMethod(instance, method.getName(), this.value);
        }

    }

    final static class DynamicPropertyMetadata extends Metadata {

        private final Method method;

        private final TagAttribute attribute;

        private final Class<?> type;

        public DynamicPropertyMetadata(Method method, TagAttribute attribute) {
            this.method = method;
            this.type = method.getParameterTypes()[0];
            this.attribute = attribute;
        }

        public void applyMetadata(FaceletContext ctx, Object instance) {
            ReflectUtil.executeMethod(instance, method.getName(), new Object[]{attribute.getObject(ctx, type)});
        }
    }
}
