/*******************************************************************************
 * 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.designtime.internal.view;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.core.Signature;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.runtime.internal.model.ViewObject;
import org.eclipse.jst.jsf.common.runtime.internal.model.behavioural.ActionSourceInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.behavioural.ActionSourceInfo2;
import org.eclipse.jst.jsf.common.runtime.internal.model.behavioural.EditableValueHolderInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.behavioural.INamingContainerInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.behavioural.ValueHolderInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentFactory;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterDecorator;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorDecorator;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IComponentPropertyHandler;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IComponentTagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IConverterTagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagAttributeHandler;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.ITagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IValidatorTagElement;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService.ElementData;
import org.eclipse.jst.jsf.designtime.internal.view.mapping.ICustomViewMapper;
import org.eclipse.jst.jsf.designtime.internal.view.mapping.ICustomViewMapper.PropertyMapping;
import org.eclipse.jst.jsf.designtime.internal.view.mapping.viewmapping.CustomViewMapperExtensionLoader;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

/**
 * A strategy for constructing view objects.
 * 
 * @author cbateman
 * 
 */
public class XMLViewObjectConstructionStrategy extends
        ViewObjectConstructionStrategy<Element>
{
    private static final String               GENERATED_ID = "_generatedId"; //$NON-NLS-1$
    private final ComponentConstructionData   _constructionData;
    private final XMLViewDefnAdapter          _adapter;
    private final XMLViewObjectMappingService _mappingService;

    /**
     * @param adapter
     *            MUST NOT BE NULL
     * @param constructionData
     *            MUST NOT BE NULL
     * @param mappingService
     *            MAY BE NULL
     */
    public XMLViewObjectConstructionStrategy(final XMLViewDefnAdapter adapter,
            final ComponentConstructionData constructionData,
            final XMLViewObjectMappingService mappingService)
    {
        super();
        if (adapter == null || constructionData == null)
        {
            throw new IllegalArgumentException(
                    "adapter and constructionData must not be null"); //$NON-NLS-1$
        }
        _constructionData = constructionData;
        _adapter = adapter;
        _mappingService = mappingService;
    }

    @Override
    public ViewObject createViewObject(final Element element,
            final ITagElement tagElement)
    {
        try
        {
            if (tagElement instanceof IComponentTagElement)
            {
                String id = null;

                // only generate ids for non-viewroot components. This will
                // make the generated id's more faithful to runtime since the
                // running count won't be incremented for view roots (as they
                // won't at runtime).
                final ComponentTypeInfo typeInfo = ((IComponentTagElement) tagElement)
                        .getComponent();

                if (!"javax.faces.ViewRoot".equals(typeInfo.getComponentType())) //$NON-NLS-1$
                {
                    id = calculateId(element, _constructionData);
                }
                return findBestComponent(tagElement.getUri(), element, id,
                        (IComponentTagElement) tagElement);
            }
            else if (tagElement instanceof IConverterTagElement)
            {
                final ConverterTypeInfo typeInfo = ((IConverterTagElement) tagElement)
                        .getConverter();
                // TODO: validate when no parent
                ComponentInfo parent = _constructionData.getParent();
                parent = findFirstParent(
                        ComponentFactory.INTERFACE_VALUEHOLDER, parent);
                if (parent != null)
                {
                    parent.addDecorator(
                            new ConverterDecorator(parent, typeInfo),
                            ComponentFactory.CONVERTER);
                }
                // TODO: else validate problem
            }
            else if (tagElement instanceof IValidatorTagElement)
            {
                final ValidatorTypeInfo typeInfo = ((IValidatorTagElement) tagElement)
                        .getValidator();
                ComponentInfo parent = _constructionData.getParent();
                parent = findFirstParent(
                        ComponentFactory.INTERFACE_EDITABLEVALUEHOLDER, parent);
                if (parent != null)
                {
                    parent.addDecorator(
                            new ValidatorDecorator(parent, typeInfo),
                            ComponentFactory.VALIDATOR);
                }
                // TODO :else validate problem
            }
        }
        catch (final Exception e)
        {
            // log and ignore if an individual construction fails
            JSFCorePlugin.log(e, "Error constructing view object"); //$NON-NLS-1$
        }
        return null;
    }

    private ComponentInfo findFirstParent(final String matchingType,
            final ComponentInfo start)
    {
        ComponentInfo parent = start;

        while (parent != null && parent.getComponentTypeInfo() != null
                && !parent.getComponentTypeInfo().isInstanceOf(matchingType))
        {
            parent = parent.getParent();
        }
        return parent;
    }

    private ComponentInfo findBestComponent(final String uri,
            final Element srcElement, final String id,
            final IComponentTagElement tagElement)
    {
        ComponentInfo bestComponent = null;

        final ComponentInfo parent = _constructionData.getParent();

        final Map<String, Object> initMap = new HashMap<String, Object>();
        final Map<String, String> attributeToPropertyMap = new HashMap<String, String>();
        populateInitMap(uri, initMap, srcElement, tagElement,
                attributeToPropertyMap);

        if (initMap.get("id") == null) //$NON-NLS-1$
        {
            // id must be set
            initMap.put("id", id); //$NON-NLS-1$
        }

        final ComponentTypeInfo typeInfo = tagElement.getComponent();

        // if we have a well-established base type, try that first
        // sub-classes must occur before superclasses to ensure most accurate
        // detection.
        if (typeInfo.isInstanceOf(ComponentFactory.BASE_CLASS_UIINPUT))
        {
            bestComponent = ComponentFactory.createUIInputInfo(parent,
                    typeInfo, initMap);
        }
        else if (typeInfo.isInstanceOf(ComponentFactory.BASE_CLASS_UIOUTPUT))
        {
            bestComponent = ComponentFactory.createUIOutputInfo(parent,
                    typeInfo, initMap);
        }
        else if (typeInfo.isInstanceOf(ComponentFactory.BASE_CLASS_UICOMMAND))
        {
            bestComponent = ComponentFactory.createUICommandInfo(parent,
                    typeInfo, initMap);
        }
        else if (typeInfo.isInstanceOf(ComponentFactory.BASE_CLASS_UIDATA))
        {
            bestComponent = ComponentFactory.createUIDataInfo(parent, typeInfo,
                    initMap);
        }
        else if (typeInfo.isInstanceOf(ComponentFactory.BASE_CLASS_UIFORM))
        {
            // TODO: how handle prepend ids?
            bestComponent = ComponentFactory.createUIFormInfo(parent, typeInfo,
                    initMap);
        }
        else
        {
            // default
            bestComponent = ComponentFactory.createComponentInfo(
                    _constructionData.getParent(), typeInfo, initMap);
        }

        addTypeAdapters(bestComponent);
        maybeMapXMLToViewObjects(bestComponent, srcElement,
                attributeToPropertyMap, _constructionData.getDocument());
        maybeUpdateViewObject(bestComponent, srcElement, tagElement);
        return bestComponent;
    }

    // TODO: move to view definition adapter?
    private void populateInitMap(final String uri,
            final Map<String, Object> initMap, final Element srcElement,
            final IComponentTagElement tagElement,
            final Map<String, String> attributeToPropertyMap)
    {
        final ComponentTypeInfo typeInfo = tagElement.getComponent();
        final Map<String, ITagAttributeHandler> attributeHandlers = tagElement
                .getAttributeHandlers();

        final NamedNodeMap nodeMap = srcElement.getAttributes();

        if (nodeMap != null && attributeHandlers != null)
        {
            Map<String, JDTBeanProperty> properties = null;

            for (int i = 0; i < nodeMap.getLength(); i++)
            {
                final Attr attr = (Attr) nodeMap.item(i);
                if (attr != null)
                {
                    final String name = attr.getLocalName();

                    if (name != null)
                    {
                        final ITagAttributeHandler attrHandler = attributeHandlers
                                .get(name);
                        if (attrHandler instanceof IComponentPropertyHandler)
                        {
                            if (properties == null) 
                            {
                                properties = DTComponentIntrospector.getBeanProperties(typeInfo, _constructionData.getProject());
                            }
                            mapComponentProperty(uri, srcElement, properties,
                                    (IComponentPropertyHandler) attrHandler,
                                    attr, name, initMap, attributeHandlers,
                                    attributeToPropertyMap);
                        }
                    }
                }
            }
        }
    }

    private void mapComponentProperty(final String uri,
            final Element srcElement,
            final Map<String, JDTBeanProperty> properties,
            final IComponentPropertyHandler attrHandler, final Attr attr,
            final String attributeName, final Map initMap,
            final Map<String, ITagAttributeHandler> attributeHandlers,
            final Map<String, String> attributeToPropertyMap)
    {
        final String propertyName = attrHandler.getPropertyName();
        if (properties.containsKey(propertyName))
        {
            final String id = attrHandler.getCustomHandler();

            ICustomViewMapper mapper = null;

            if (id != null)
            {
                mapper = CustomViewMapperExtensionLoader
                        .getCustomViewMapper(id);
                if (mapper != null)
                {
                    final PropertyMapping mapping = mapper
                            .mapToComponentProperty(uri, srcElement, attr);
                    if (mapping != null)
                    {
                        initMap.put(mapping.getName(), mapping.getProperty());
                        attributeToPropertyMap.put(attributeName, mapping
                                .getName());
                        return;
                    }
                }
            }

            final String value = attr.getValue();
            if (value != null)
            {
                final Object convertedValue = convertFromString(value,
                        properties.get(propertyName));
                initMap.put(propertyName, convertedValue);
            }
            attributeToPropertyMap.put(attributeName, propertyName);
        }
    }

    private void maybeMapXMLToViewObjects(final ViewObject mappedObject,
            final Element node,
            final Map<String, String> attributeToProperties,
            final IDocument document)
    {
        if (mappedObject != null && _mappingService != null)
        {
            final String uri = _adapter.getNamespace(node, document);
            final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
                    .getContext(document, node);
            final ElementData elementData = XMLViewObjectMappingService
                    .createElementData(uri, node.getLocalName(), context,
                            attributeToProperties);

            _mappingService.createMapping(elementData, mappedObject);
        }
    }

    private void maybeUpdateViewObject(final ComponentInfo bestComponent,
            final Element srcElement, final ITagElement tagElement)
    {
        if (srcElement.getAttributes() == null)
            return;

        for (int i = 0; i < srcElement.getAttributes().getLength(); i++)
        {
            final Attr attr = (Attr) srcElement.getAttributes().item(i);
            final Map<String, ITagAttributeHandler> attributeHandlers = tagElement
                    .getAttributeHandlers();

            if (attributeHandlers != null)
            {
                final ITagAttributeHandler handler = attributeHandlers.get(attr
                        .getLocalName());

                if (handler != null)
                {
                    final String id = handler.getCustomHandler();

                    ICustomViewMapper mapper = null;

                    if (id != null)
                    {
                        mapper = CustomViewMapperExtensionLoader
                                .getCustomViewMapper(id);
                        if (mapper != null)
                        {
                            mapper.doAttributeActions(bestComponent,
                                    srcElement, attr);
                        }
                    }
                }
            }
        }
    }

    private Object convertFromString(final String convertValue,
            final JDTBeanProperty ofThisType)
    {
        final String signature = ofThisType.getTypeSignature();

        Object result = null;
        switch (Signature.getTypeSignatureKind(signature))
        {
            case Signature.BASE_TYPE_SIGNATURE:
                result = convertFromBaseType(convertValue, signature);
            break;

            case Signature.CLASS_TYPE_SIGNATURE:
                if (TypeConstants.TYPE_STRING.equals(signature))
                {
                    result = convertValue;
                }
                else if (TypeConstants.TYPE_JAVAOBJECT.equals(signature))
                {
                    result = convertValue;
                }
            break;
        }

        return result;
    }

    // TODO: does this belong somewhere else?
    private Object convertFromBaseType(final String convertValue,
            final String signature)
    {
        if (Signature.SIG_BOOLEAN.equals(signature))
        {
            return Boolean.valueOf(convertValue);
        }
        else if (Signature.SIG_INT.equals(signature)
                || Signature.SIG_BYTE.equals(signature)
                || Signature.SIG_SHORT.equals(signature))
        {
            try
            {
                return Integer.valueOf(convertValue);
            }
            catch (final NumberFormatException nfe)
            {
                return null;
            }
        }
        else if (Signature.SIG_LONG.equals(convertValue))
        {
            try
            {
                return Long.valueOf(convertValue);
            }
            catch (final NumberFormatException nfe)
            {
                return null;
            }
        }

        return null;
    }

    private void addTypeAdapters(final ComponentInfo component)
    {
        final String[] interfaceNames = component.getComponentTypeInfo()
                .getInterfaces();
        final Set interfaceNameSets = new HashSet();

        for (final String interfaceName : interfaceNames)
        {
            interfaceNameSets.add(interfaceName);
        }

        // don't replace intrinsic adapters
        if (interfaceNameSets.contains(ComponentFactory.INTERFACE_ACTIONSOURCE))
        {
            // an ActionSource2 is-a ActionSource
            if (interfaceNameSets
                    .contains(ComponentFactory.INTERFACE_ACTIONSOURCE2)
                    && component.getAdapter(ComponentFactory.ACTION_SOURCE2) == null)
            {
                component.addAdapter(ComponentFactory.ACTION_SOURCE2,
                        new ActionSourceInfo2(null, null, false, null));
            }

            if (component.getAdapter(ComponentFactory.ACTION_SOURCE) == null)
            {
                component.addAdapter(ComponentFactory.ACTION_SOURCE,
                        new ActionSourceInfo(null, null, false));
            }
        }

        if (interfaceNameSets.contains(ComponentFactory.INTERFACE_VALUEHOLDER))
        {
            // a EditableValueHolder is-a ValueHolder
            if (interfaceNameSets
                    .contains(ComponentFactory.INTERFACE_EDITABLEVALUEHOLDER)
                    && component
                            .getAdapter(ComponentFactory.EDITABLE_VALUE_HOLDER) == null)
            {
                component.addAdapter(ComponentFactory.EDITABLE_VALUE_HOLDER,
                        new EditableValueHolderInfo(null, null, null, false,
                                false, true, false, null, null, null));
            }

            if (component.getAdapter(ComponentFactory.VALUE_HOLDER) == null)
            {
                component.addAdapter(ComponentFactory.VALUE_HOLDER,
                        new ValueHolderInfo(null, null, null));
            }
        }

        if (interfaceNameSets
                .contains(ComponentFactory.INTERFACE_NAMINGCONTAINER)
                && component.getAdapter(ComponentFactory.NAMING_CONTAINER) == null)
        {
            component.addAdapter(ComponentFactory.NAMING_CONTAINER,
                    INamingContainerInfo.ADAPTER);
        }
    }

    /**
     * @param element
     * @param constructionData
     * @return the id for element either derived from the element using getId or
     *         if not present, using a generation algorithm
     */
    protected String calculateId(final Element element,
            final ComponentConstructionData constructionData)
    {
        final String id = _adapter.getId(element);
        if (id != null)
        {
            return id;
        }
        // TODO: improve this
        final String prefix = _adapter.getGeneratedIdPrefix();
        return (prefix != null ? prefix : GENERATED_ID)
                + constructionData.increment();
    }

    /**
     * @return the construction data for this strategy
     */
    public final ComponentConstructionData getConstructionData()
    {
        return _constructionData;
    }
}
