/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common.runtime.internal.model.component;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.eclipse.jst.jsf.common.runtime.internal.model.ViewObject;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.AbstractVisitor.VisitationPolicy;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.FacetDecorator;

/**
 * Models a basic UI component instance
 * 
 * TODO: should implement a visitor pattern to traverse component trees
 * 
 * @author cbateman
 * 
 */
public class ComponentInfo extends ViewObject implements Serializable,
        IVisitable
{
    /**
     * serializable id
     */
    private static final long             serialVersionUID     = 2517204356825585699L;

    private final static int              DEFAULT_ARRAY_SIZE   = 4;

    private transient BeanPropertyManager _beanPropertyManager;
    /**
     * Encapsulates all of the data for the view object
     */
    protected final ComponentInfoData     _data;

    // initialized
    // by
    // getBeanProperties

    /**
     * @param id
     * @param parent
     * @param componentTypeInfo
     * @param isRendered
     */
    protected ComponentInfo(final String id, final ComponentInfo parent,
            final ComponentTypeInfo componentTypeInfo, final boolean isRendered)
    {
        super(new ComponentInfoData(id, parent, componentTypeInfo, isRendered));
        _data = (ComponentInfoData) super.getData();
        
        final Set propExclude = new HashSet();
        propExclude.add("attributeNames"); //$NON-NLS-1$
        propExclude.add("componentTypeInfo"); //$NON-NLS-1$
        propExclude.add("valueChangeListeners"); //$NON-NLS-1$
        propExclude.add("visitableChildren"); //$NON-NLS-1$

        _beanPropertyManager = new BeanPropertyManager(this, propExclude);
    }

    /**
     * @param data
     */
    protected ComponentInfo(final ComponentInfoData data)
    {
        super(data);
        _data = data;
    }

    /**
     * Construct a new component info using the attributes keyed by name in
     * attributes to set values. The names must match the corresponding bean
     * property names. Primitives should be wrapped in their corresponding
     * object types. Exceptions will be thrown if there is a type mismatch on an
     * expected type. Number will be used for all numeric primitive wrappers an
     * the corresponding "to" will be called.
     * 
     * @param parent
     * @param componentTypeInfo
     * @param attributes
     * @throws ClassCastException
     *             if an attribute's value doesn't match the expected type
     * @throws NullPointerException
     *             if an attribute value is null for a value whose type is
     *             expected to be primitive
     * @throws IllegalArgumentException
     *             if attributes does not contain a required key.
     */
    protected ComponentInfo(final ComponentInfo parent,
            final ComponentTypeInfo componentTypeInfo, final Map attributes)
    {
        this(getStringProperty("id", attributes, false), parent, //$NON-NLS-1$
                componentTypeInfo, getBooleanProperty("rendered", attributes, false)); //$NON-NLS-1$
    }

    /**
     * @param key
     * @param attributes
     * @param mandatory
     * @return the value in attributes at location key, forcing a
     *         ClassCastException if it turns out not to be a String.
     * @throws ClassCastException
     *             if the attribute for key is not a String
     * @throws IllegalArgumentException
     *             if the attribute for key is null but mandatory is true.
     */
    protected static String getStringProperty(final String key,
            final Map attributes, final boolean mandatory)
    {
        final Object value = attributes.get(key);

        if (mandatory && value == null)
        {
            throw new IllegalArgumentException(key
                    + " is a mandatory attribute"); //$NON-NLS-1$
        }
        return (String) value;
    }

    /**
     * @param key
     * @param attributes
     * @param mandatory 
     * 
     * @return the value in attributes at location, forcing a ClassCastExceptio
     *         if it is not a Boolean and mandatory.  returns false if no value
     *         and not mandatory
     * @throws IllegalArgumentException
     *             if key is not found and value is mandatory
     */
    protected static boolean getBooleanProperty(final String key,
            final Map attributes, final boolean mandatory)
    {
        final Boolean value = (Boolean) attributes.get(key);

        if (value == null)
        {
            if (mandatory)
            {
                throw new IllegalArgumentException(key + "is mandatory"); //$NON-NLS-1$
            }
            return false;
        }

        return value.booleanValue();
    }

    /**
     * @param key
     * @param attributes
     * @return the integer property for key. Casts the value to Number and calls
     *         Number.intValue().  0 if no value.
     */
    protected static int getIntegerProperty(final String key,
            final Map attributes)
    {
        final Number value = (Number) attributes.get(key);

        if (value == null)
        {
            return 0;
        }

        return value.intValue();
    }

    /**
     * @param key
     * @param attributes
     * @return the component info value from attributes
     */
    protected static ComponentInfo getComponentProperty(final String key,
            final Map attributes)
    {
        return (ComponentInfo) attributes.get(key);
    }

    /**
     * @return the id
     */
    public final String getId()
    {
        return _data.getId();
    }

    /**
     * @return the component type info
     */
    public final ComponentTypeInfo getComponentTypeInfo()
    {
        return _data.getComponentTypeInfo();
    }

    /**
     * Pre-condition: isModifiable() == true Post-condition: getChildren() will
     * return an empty list.
     */
    protected final void clearChildren()
    {
        _data.getChildren().clear();
    }

    /**
     * @return the children. List is unmodifiable. List contains all children
     *         including facets.
     */
    public final List/* <ComponentInfo> */getChildren()
    {
        if (_data.isProtected())
        {
            return _data.getChildren();
        }
        return Collections.unmodifiableList(_data.getChildren());
    }

    /**
     * Get the sub-set of {@link #getChildren()} that are facets. This is a
     * convenience method for {@link #getDecorators(Class)}
     * 
     * @return all component children that are facets
     */
    public final List getFacets()
    {
        return getDecorators(ComponentFactory.FACET);
    }

    /**
     * @param childComponent
     */
    public final void addChild(final ComponentInfo childComponent)
    {
        if (childComponent == this)
        {
            throw new IllegalArgumentException(
                    "A component cannot be its own child"); //$NON-NLS-1$
        }
        _data.addChild(childComponent);
        // we need to reset the child's parent to me
        childComponent.setParent(this);
    }

    /**
     * @param parent
     */
    public final void setParent(ComponentInfo parent)
    {
        _data.setParent(parent);
    }

    /**
     * @param name
     * @param facetComponent
     */
    public final void addFacet(final String name,
            final ComponentInfo facetComponent)
    {
        addChild(facetComponent);
        addDecorator(new FacetDecorator(name, facetComponent));
    }

    /**
     * @param component
     * @return if component corresponds to a facet of this component, returns
     *         the name of that facet. Returns null if not found.
     */
    public final String getFacetName(final ComponentInfo component)
    {
        if (component == null)
        {
            return null;
        }

        final List facets = getDecorators(ComponentFactory.FACET);

        for (final Iterator it = facets.iterator(); it.hasNext();)
        {
            final FacetDecorator facet = (FacetDecorator) it.next();
            if (component == facet.getDecorates())
            {
                return facet.getName();
            }
        }

        // component is not a facet
        return null;
    }

    /**
     * @param name
     * @return if this has a facet called name, then returns it's single root
     *         component.
     */
    public final ComponentInfo getFacet(final String name)
    {
        if (name == null)
        {
            return null;
        }

        final List facets = getDecorators(ComponentFactory.FACET);

        for (final Iterator it = facets.iterator(); it.hasNext();)
        {
            final FacetDecorator facet = (FacetDecorator) it.next();
            if (name.equals(facet.getName()))
            {
                return facet.getDecorates();
            }
        }

        // not found
        return null;
    }

    public String toString()
    {
        final String parentId = getParent() != null ? getParent().getId()
                : "null"; //$NON-NLS-1$
        String toString = getMostSpecificComponentName() + ": id=" //$NON-NLS-1$
                + _data.getId() + ", parentId: " + parentId + ", family=" //$NON-NLS-1$ //$NON-NLS-2$
                + getComponentTypeInfo().getComponentFamily() + ", render=" //$NON-NLS-1$
                + getComponentTypeInfo().getRenderFamily() + ", rendered=" //$NON-NLS-1$
                + isRendered();

        // use bean introspection to dump child properties
        if (this.getClass() != ComponentInfo.class)
        {
            toString += dumpProperties();
        }

        return toString;
    }

    private String dumpProperties()
    {
        String properties = ""; //$NON-NLS-1$
        try
        {
            final BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass(),
                    ComponentInfo.class);

            final PropertyDescriptor[] descriptors = beanInfo
                    .getPropertyDescriptors();
            for (int i = 0; i < descriptors.length; i++)
            {
                final PropertyDescriptor desc = descriptors[i];
                final String name = desc.getName();
                final Object valueObj = desc.getValue(name);
                final String value = valueObj != null ? valueObj.toString()
                        : "null"; //$NON-NLS-1$
                properties += ", " + name + "=" + value; //$NON-NLS-1$ //$NON-NLS-2$
            }
        }
        catch (final IntrospectionException e)
        {
            return "Error introspecting bean: " + e.getLocalizedMessage(); //$NON-NLS-1$
        }

        return properties;
    }

    /**
     * @return used for toString. Clients should not use.
     */
    protected String getMostSpecificComponentName()
    {
        return "UIComponent"; //$NON-NLS-1$
    }

    /**
     * @return the parent of this component or null.
     */
    public final ComponentInfo getParent()
    {
        return _data.getParent();
    }

    /**
     * @return the rendered flag
     */
    public final boolean isRendered()
    {
        return _data.isRendered();
    }

    public synchronized void addAdapter(final Class adapterType,
            final Object adapter)
    {
        super.addAdapter(adapterType, adapter);

        // force an update on the next call to getBeanProperties
        _beanPropertyManager.reset();
    }

    public synchronized Object removeAdapter(final Class adapterType)
    {
        final Object removed = super.removeAdapter(adapterType);

        _beanPropertyManager.reset();

        return removed;
    }

    /**
     * @return the set of all bean property names for this component. The set is
     *         unmodifiable and will throw exceptions if modification is
     *         attempted.
     */
    protected final Map/* <String, ComponentBeanProperty> */getBeanProperties()
    {
        return Collections.unmodifiableMap(_beanPropertyManager
                .getBeanProperties());
    }

    /**
     * @author cbateman
     * 
     */
    public static class ComponentInfoData extends ViewObjectData
    {
        /**
         * 
         */
        private static final long         serialVersionUID                = 5052732412917986062L;
        /**
         * the component id
         */
        private final String              _id;
        /**
         * the component's parent or null if none
         */
        private ComponentInfo             _parent;

        /**
         * the type info for this component
         */
        protected final ComponentTypeInfo _componentTypeInfo;
        /**
         * the rendered flage
         */
        protected final boolean           _isRendered;

        private List                     /* <ComponentInfo> */_children = new ArrayList(
                                                                                  DEFAULT_ARRAY_SIZE);

        /**
         * @param id
         * @param parent
         * @param componentTypeInfo
         * @param isRendered
         */
        public ComponentInfoData(final String id, ComponentInfo parent,
                ComponentTypeInfo componentTypeInfo, boolean isRendered)
        {
            super(false);
            _id = id;
            _parent = parent;
            _componentTypeInfo = componentTypeInfo;
            _isRendered = isRendered;
        }

        /**
         * @param childComponent
         */
        protected void addChild(ComponentInfo childComponent)
        {
            enforceProtection();

            getChildren().add(childComponent);
        }

        /**
         * @return the modifiable list of children
         */
        protected final List/* <ComponentInfo> */getChildren()
        {
            return _children;
        }

        protected void doBeforeProtecting()
        {
            super.doBeforeProtecting();
            // compact the children array list
            if (_children.size() > 0)
            {
                _children = Collections.unmodifiableList(_children);
            }
            else
            {
                _children = Collections.EMPTY_LIST;
            }
        }

        /**
         * @return the isRendered flag
         */
        protected final boolean isRendered()
        {
            return _isRendered;
        }

        /**
         * @return the component type info flag
         */
        protected final ComponentTypeInfo getComponentTypeInfo()
        {
            return _componentTypeInfo;
        }

        /**
         * @return the parent or null if no parent
         */
        protected final ComponentInfo getParent()
        {
            return _parent;
        }

        /**
         * @param parent
         */
        protected final void setParent(ComponentInfo parent)
        {
            enforceProtection();
            _parent = parent;
        }

        /**
         * @return the component id
         */
        protected final String getId()
        {
            return _id;
        }
    }

    /**
     * This is similar to the runtime getAttributes().get(name) call. The reason
     * we don't implement a Map of all attribute values is that the implicit
     * property structure can change at any time due to add/removeAdapter. To
     * get all attributes known for a component, instead use:
     * 
     * The synchronized block is advised to protect against concurrent
     * modification exceptions on the keySet iterator.
     * 
     * @param name
     * 
     * @return the value of the attribute or null if none.
     * 
     */
    public synchronized ComponentBeanProperty getAttribute(final String name)
    {
        return (ComponentBeanProperty) getBeanProperties().get(name);
    }

    /**
     * @return the set of valid attribute names. The Set is not modifiable.
     */
    public synchronized Set/* <String> */getAttributeNames()
    {
        return getBeanProperties().keySet();
    }

    /**
     * Stores a bean property descriptor along information about which
     * implementation class declares it and what key to pass to getAdapter() in
     * order to get it.
     * 
     */
    public final static class ComponentBeanProperty
    {
        private final PropertyDescriptor _propertyDescriptor;
        private final Object             _declaringImplementation;
        private final Class              _adapterKeyClass;

        // only instantiable locally
        private ComponentBeanProperty(Class adapterKeyClass,
                Object declaringImplementationClass,
                PropertyDescriptor propertyDescriptor)
        {
            super();
            _adapterKeyClass = adapterKeyClass;
            _declaringImplementation = declaringImplementationClass;
            _propertyDescriptor = propertyDescriptor;
        }

        /**
         * @return the value of property
         */
        public final Object getValue()
        {
            final Method method = _propertyDescriptor.getReadMethod();
            if (method != null)
            {
                try
                {
                    method.setAccessible(true);
                    return method.invoke(_declaringImplementation,
                            new Object[0]);
                }
                catch (IllegalArgumentException e)
                {
                    e.printStackTrace();
                }
                catch (IllegalAccessException e)
                {
                    e.printStackTrace();
                }
                catch (InvocationTargetException e)
                {
                    e.printStackTrace();
                }
            }
            // if any step fails, return null
            return null;
        }

        /**
         * @return the property descriptor
         */
        public final PropertyDescriptor getPropertyDescriptor()
        {
            return _propertyDescriptor;
        }

        /**
         * @return the implemenation
         */
        public final Object getDeclaringImplementationClass()
        {
            return _declaringImplementation;
        }

        /**
         * @return the adapter class for the interface that the declaring
         *         implementation is providing the impl for
         */
        public final Class getAdapterKeyClass()
        {
            return _adapterKeyClass;
        }
    }

    /**
     * Manages bean property information for a component
     * 
     * @author cbateman
     * 
     */
    protected final static class BeanPropertyManager
    {
        /**
         * a map of the bean property names exposed by this component including
         * all those added by addAdapter().
         * 
         * this is synthetic based the class definition and installed adapters
         * so as long that info is available, no need to serialize.
         */
        protected transient Map              /*
                                                 * <String,
                                                 * ComponentBeanProperty>
                                                 */_beanProperties; // lazily
        private final transient ComponentInfo _component;
        private final transient Set _excludeNames;

        /**
         * @param component
         * @param excludeNames 
         */
        protected BeanPropertyManager(final ComponentInfo component,
                final Set excludeNames)
        {
            _component = component;
            _excludeNames = excludeNames;
        }

        /**
         * Will throw exception of the calling thread already holds the "this"
         * monitor lock. This is to ensure that caller always acquires locks in
         * appropriate order to prevent deadlock.
         * 
         * @return the internal set of bean properties. This Set may be modified
         *         internally.
         */
        public Map getBeanProperties()
        {
            if (Thread.holdsLock(this))
            {
                throw new IllegalStateException(
                        "Must not already own this lock"); //$NON-NLS-1$
            }

            // must always acquire component lock first to prevent deadlock
            synchronized (_component)
            {
                synchronized (this)
                {
                    if (_beanProperties == null)
                    {
                        _beanProperties = calculateAllBeanPropNames(ViewObject.class);
                    }

                    return _beanProperties;
                }
            }
        }

        /**
         * Will throw exception if the calling thread already holds the "this"
         * monitor lock. This is to ensure that caller always acquires locks in
         * appropriate order to prevent deadlock.
         * 
         * Clears the internal map and sets to null. This will force it to be
         * completely new built on the next call to getBeanProperties
         */
        public void reset()
        {
            if (Thread.holdsLock(this))
            {
                throw new IllegalStateException(
                        "Must not already own this lock"); //$NON-NLS-1$
            }

            // must always acquire component lock first to prevent deadlock
            synchronized (_component)
            {
                synchronized (this)
                {
                    if (_beanProperties != null)
                    {
                        _beanProperties.clear();
                        _beanProperties = null;
                    }
                }
            }
        }

        /**
         * @param stopClass
         * @return a synchronized map of all bean property names on this class
         *         up to stopClass, as well as all adapter property names (as
         *         though this really implemented them).
         */
        private Map calculateAllBeanPropNames(final Class stopClass)
        {
            // use a set to prevents the duplicates
            final Map allProperties = new HashMap();

            {
                final Class myClass = _component.getClass();
                final List myProperties = getOrCreateBeanProperties(myClass,
                        stopClass);

                addToMap(myProperties, _component, myClass, allProperties, _excludeNames);
            }

            {
                for (final Iterator it = _component.getAdapterMap().entrySet()
                        .iterator(); it.hasNext();)
                {
                    Map.Entry entry = (Entry) it.next();

                    final Class adapterClass = (Class) entry.getKey();
                    final Object declaringClass = entry.getValue();
                    // get all props, excluding the ones on Object.
                    final List props = getOrCreateBeanProperties(adapterClass,
                            null);
                    addToMap(props, declaringClass, adapterClass, allProperties,
                            _excludeNames);
                }
            }

            return Collections.synchronizedMap(allProperties);
        }

        private static void addToMap(
                final List/* <ComponentBeanProperty> */addThese,
                final Object declaringObject, final Class declaringAdapter,
                final Map toMe,
                Set excludeNames)
        {
            for (final Iterator it = addThese.iterator(); it.hasNext();)
            {
                final PropertyDescriptor desc = (PropertyDescriptor) it.next();

                if (!toMe.containsKey(desc.getName())
                    && !excludeNames.contains(desc.getName()))
                {
                    toMe.put(desc.getName(), new ComponentBeanProperty(
                            declaringAdapter, declaringObject, desc));
                }
            }
        }

        /**
         * lazily loaded with the local properties (those not defined using
         * adapters)
         * 
         * MUST INITIALIZE early so can synchronize on it
         */
        private transient static Map /* <Class, List<PropertyDescriptor> */PROPERTY_MAP = new HashMap();

        /**
         * @param startClass
         * @param stopClass
         * @return a unmodifiable list of properties starting from startClass.
         *         stopClass is only used if an entry doesn't already exist in
         *         PROPERTY_MAP for startClass. The method is synchronized on
         *         the PROPERTY_MAP it updates.
         */
        protected static List/* <PropertyDescriptor */getOrCreateBeanProperties(
                final Class startClass, final Class stopClass)
        {
            synchronized (PROPERTY_MAP)
            {
                List localBeanProps = (List) PROPERTY_MAP.get(startClass);

                if (localBeanProps == null)
                {
                    localBeanProps = calculateBeanProperties(startClass,
                            stopClass);
                    PROPERTY_MAP.put(startClass, Collections
                            .unmodifiableList(localBeanProps));
                }

                return localBeanProps;
            }
        }

        /**
         * @param startClass
         * @param stopClass
         * @return a List<String> containing all of the bean names between
         *         startClass and stopClass. Start class must be a descendant
         *         (sub-class, sub-sub-class etc.) of stopClass. The properties
         *         on stopClass are excluded from analysis.
         */
        private static List/* <PropertyDescriptor> */calculateBeanProperties(
                final Class startClass, final Class stopClass)
        {
            BeanInfo beanInfo;
            List names = new ArrayList();

            try
            {
                beanInfo = Introspector.getBeanInfo(startClass, stopClass);
                final PropertyDescriptor[] descriptors = beanInfo
                        .getPropertyDescriptors();

                if (descriptors != null)
                {
                    names = Arrays.asList(descriptors);
                }
            }
            catch (final IntrospectionException e)
            {
                e.printStackTrace();
            }
            return names;
        }

    }

    /**
     * Visits this node and it's entire tree and makes all nodes protected.
     */
    public final void setSubtreeProtected()
    {
        // lock children first
        final ComponentTreeVisitor protectionVisitor = new ComponentTreeVisitor(VisitationPolicy.ChildrenFirstPolicy)
        {
            public void visit(ComponentInfo component)
            {
                component.setProtected();
            }
        };
        
        accept(protectionVisitor);
    }

    public void accept(AbstractVisitor visitor)
    {
        // check policy ordering
        if (visitor.getPolicy().getOrdering() == VisitationPolicy.VISIT_PARENT_FIRST)
        {
            visitor.visit(this);
            visitChildren(visitor);
        }
        else
        {
            visitChildren(visitor);
            visitor.visit(this);
        }
    }

    private void visitChildren(AbstractVisitor visitor)
    {
        for (final Iterator it = getVisitableChildren(); it.hasNext();)
        {
            visitor.visit(it.next());
        }
    }

    public Iterator getVisitableChildren()
    {
        return getChildren().iterator();
    }
}