/*******************************************************************************
 * Copyright (c) 2001, 2010 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * 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);
            //Bug 269050 - IllegalArgumentException in createMapping() method
            if (elementData != null) {
            	_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;
    }
}
